<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                * redux-actions是一個實用的庫,讓編寫redux狀態管理變得簡單起來。redux-action產生的動作是[FSA](https://github.com/redux-utilities/flux-standard-action)標準的 ### 5.1 單個action #### 5.1.1 actions\\counter.js src\\store\\actions\\counter.js ~~~ import * as types from '../action-types'; //import { createAction } from 'redux-actions'; function createAction(type,payloadCreator){ return function actionCreator(...args){ return {type,payload:payloadCreator(...args)}; } } const add = createAction(types.ADD,(payload)=>payload*2); const minus = createAction(types.MINUS,(payload)=>payload*2); export default { add, minus } ~~~ #### 5.1.2 reducers\\counter.js src\\store\\reducers\\counter.js ~~~ import * as types from '../action-types'; //import {handleAction} from 'redux-actions'; import actions from '../actions/counter'; function handleAction(type,reducer ,defaultState){ return function(state=defaultState,action){ if(action.type === type){ return reducer(state,action); } return state; } } const initialState = {number:0}; const reducer = handleAction(types.ADD,(state,action)=>{ return { ...state,number:state.number+action.payload } },initialState); export default reducer; ~~~ ### 5.2 多個action #### 5.2.1 actions\\counter.js actions\\counter.js ~~~ import * as types from '../action-types'; //import { createAction,createActions } from 'redux-actions'; export default createActions({ [types.ADD]:(payload)=>payload*2, [types.MINUS]:(payload)=>payload*2 }); function createActions(actions){ let newActions = {}; for(let type in actions){ newActions[type]= function(...args){ return {type,payload:actions[type](...args)} } } return newActions; } ~~~ #### 5.2.2 reducers\\counter.js reducers\\counter.js ~~~ import * as types from '../action-types'; //import {handleAction,handleActions } from 'redux-actions'; import actions from '../actions/counter'; const initialState = {number:0}; function handleActions(reducers,initialState){ return function(state=initialState,action){ let types = Object.keys(reducers); for(let i=0;i<types.length;i++){ let type = types[i]; if(type === action.type){ return reducers[type](state,action); } } return state; } } export default handleActions({ [types.ADD]:(state,action)=>{ return { ...state,number:state.number+action.payload } }, [types.MINUS]:(state,action)=>{ return { ...state,number:state.number-action.payload } } },initialState); ~~~ ## reselect * 使用Redux管理React應用狀態時,`mapStateToProps`方法作為從`Redux Store`上獲取數據過程中的重要一環,它一定不能有性能缺陷,它本身是一個函數,通過計算返回一個對象,這個計算過程通常是基于Redux Store狀態樹進行的,而很明顯的Redux狀態樹越復雜,這個計算過程可能就越耗時,我們應該要能夠盡可能減少這個計算過程,比如重復在相同狀態下渲染組件,多次的計算過程顯然是多余的,我們是否可以緩存該結果呢?這個問題的解決者就是`reselect`,它可以提高應用獲取數據的性能 * `reselect`的原理是,只要相關狀態不變,即直接使用上一次的緩存結果 ### 6.1 基本用法 * reselect通過創建選擇器(selectors),該函數接受一個state參數,然后返回我們需要在mapStateToProps方法內返回對象的某一個數據項,一個選擇器的處理可以分為兩個步驟 * 接受state參數,根據我們提供的映射函數數組分別進行計算,如果返回結果和上次第一步的計算結果一致,說明命中緩存,則不進行第二步計算,直接返回上次第二步的計算結果,否則繼續第二步計算。第一步的結果比較,通常僅僅是===相等性檢查,性能是足夠的 * 根據第一步返回的結果,計算并返回最終結果 * 需要注意的是,傳入createSelector的映射函數返回的狀態應該是不可變的,因為默認緩存命中檢測函數使用引用檢查,如果使用JavaScript對象,僅改變該對象的某一屬性,引用檢測是無法檢測到屬性變更的,這將導致組件無法響應更新 ~~~ //import { createSelector } from 'reselect' function createSelector(selector,reducer){ let lastState; let value; return function(state){ let newState = selector(state); if(lastState !== newState){ value = reducer(newState); lastState = newState; } return value; } } const counterSelector = state => state.counter; const getCounterSelector = createSelector( counterSelector, counter => { console.log('重新計算number') return counter.number; } ) let initialState = { counter: { number:0 } } console.log(getCounterSelector(initialState)); console.log(getCounterSelector(initialState)); ~~~ ~~~ +console.log(getCounterSelector(initialState)); +initialState.counter.number+=1; +console.log(getCounterSelector(initialState)); ~~~ ~~~ + console.log(getCounterSelector(initialState)); + initialState.counter={number:1} + console.log(getCounterSelector(initialState)); ~~~ ~~~ +const immutable = require("immutable"); +let initialState = immutable.Map({counter: {number:0}}) +console.log(getCounterSelector(initialState.toJS())); +initialState = initialState.setIn(['counter','number'],1); +console.log(getCounterSelector(initialState.toJS())); ~~~ ### 6.2 案例 #### 6.2.1 src\\index.js src\\index.js ~~~ import React from 'react'; import ReactDOM from 'react-dom'; import Counter1 from './components/Counter1'; import Counter2 from './components/Counter2'; import {Provider} from 'react-redux'; import store from './store'; ReactDOM.render( <Provider store={store}> <><Counter1/><Counter2/></> </Provider>,document.getElementById('root')); ~~~ #### 6.2.2 Counter1.js src\\components\\Counter1.js ~~~ import React from 'react'; import {connect} from 'react-redux'; import { createSelector } from 'reselect' import actions from '../store/actions/counter1'; class Counter extends React.Component{ render(){ return ( <div> <p>{this.props.number}</p> <button onClick={this.props.add}>+</button> <button onClick={this.props.minus}>-</button> </div> ) } } const getCounterSelector = state => state.get('counter1'); const counterSelector = createSelector( getCounterSelector, counter1 =>{ console.log('重新計算counter1',counter1); return counter1; } ) export default connect( state=>counterSelector(state), actions )(Counter) ~~~ #### 6.2.3 Counter2.js src\\components\\Counter2.js ~~~ import React from 'react'; import {connect} from 'react-redux'; import { createSelector } from 'reselect' import actions from '../store/actions/counter2'; class Counter extends React.Component{ render(){ return ( <div> <p>{this.props.number}</p> <button onClick={()=>this.props.add(5)}>+</button> <button onClick={()=>this.props.minus(5)}>-</button> </div> ) } } const getCounterSelector = state => state.get('counter2'); const counterSelector = createSelector( getCounterSelector, counter2 =>{ console.log('重新計算counter2',counter2) return counter2; } ) export default connect( state=>counterSelector(state), actions )(Counter) ~~~ #### 6.2.4 src\\store\\index.js src\\store\\index.js ~~~ import {createStore,applyMiddleware} from 'redux'; import reducer from './reducers'; import logger from 'redux-logger'; import thunk from 'redux-thunk'; import promise from 'redux-promise'; let store = applyMiddleware(promise,thunk,logger)(createStore)(reducer); export default store; ~~~ #### 6.2.5 reducers\\index.js src\\store\\reducers\\index.js ~~~ //import {combineReducers} from 'redux'; import {combineReducers} from 'redux-immutable'; import counter1 from './counter1'; import counter2 from './counter2'; export default combineReducers({ counter1, counter2 }); ~~~ #### 6.2.6 reducers\\counter1.js src\\store\\reducers\\counter1.js ~~~ import * as types from '../action-types'; import actions from '../actions/counter'; const initialState = {number:0}; export default function(state=initialState,action){ switch(action.type){ case types.ADD1: return {number:state.number+1}; case types.MINUS1: return {number:state.number-1}; default: return state; } }; ~~~ #### 6.2.7 reducers\\counter2.js src\\store\\reducers\\counter2.js ~~~ import * as types from '../action-types'; import actions from '../actions/counter'; const initialState = {number:0}; export default function(state=initialState,action){ switch(action.type){ case types.ADD2: return {number:state.number+1}; case types.MINUS2: return {number:state.number-1}; default: return state; } }; ~~~ #### 6.2.8 counter1.js src\\store\\actions\\counter1.js ~~~ import * as types from '../action-types'; export default { add(){ return {type:types.ADD1} }, minus(){ return {type:types.MINUS1} } } ~~~ #### 6.2.9 actions\\counter2.js src\\store\\actions\\counter2.js ~~~ import * as types from '../action-types'; export default { add(){ return {type:types.ADD2} }, minus(){ return {type:types.MINUS2} } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看