redux常見概念

redux

redux流程圖

gif地址javascript

  1. Web 應用是一個狀態機,視圖與狀態是一一對應的。java

  2. 全部的狀態,保存在一個對象裏面。react

redux不依賴於reactgit

state

就是app中數據組成的樹,也是一個普通的js對象。樹的結構根據應用的須要自行決定,官方推薦的方式是分爲三種數據:github

  1. 後端提供的應用數據redux

  2. 應用狀態數據 (某條數據是否選中)後端

  3. ui組件的數據(彈窗是否打開)app

action

action是一個描述「發生了什麼」的普通對象
action是咱們開發的應用程序和store間通訊的信息,它就是普通的js對象,結構是自定義的,信息量應儘量小。
例如:ide

{
  type: 'ADD_NEWS',
  text: '這是一條新聞'
}

action creator

action建立函數函數

function addNews(text) {
  return {
    type: 'ADD_NEWS',
    text
  }
}

reducer

reducer是根據action來返回一個全新state的純函數。

function newsReducer(state = initialState, action) {
  switch (action) {
      case: 'ADD_NEWS':
        return [...state, text]
        break;
    default:
        return state;
  }
}

store

store只是把actions和reducers聯繫在一塊兒的對象,並非傳統意義上象徵數據的東西。

const store = createStore(rootReducer, defaultState)

提供 getState() 方法獲取 state
提供 dispatch(action) 方法更新 state; store.dispatch(addNews('這是一條新聞'))
經過 subscribe(listener) 註冊監聽器
經過 subscribe(listener) 返回的函數註銷監聽器。

react-redux

容器組件(container)和展現組件(component)

component只關注展現層。
container是經過connect方法把redux和展現組件關聯起來的東西。

combineReducers

combineReducers(reducers)
傳入reducers做爲參數, reducers是一個object,如 {news: function() {...}, blogs: function() {...}}
返回一個遍歷執行全部reducers的reducer函數,每一個reducer只處理state中對應本身key的部分.

bindActionCreators

bindActionCreator

function bindActionCreator(actionCreator, dispatch) {
  return (...args) => dispatch(actionCreator(...args))
}

bindActionCreators就是把多個actionCreator變成會去執行dispatch的函數,而且返回這個對象。

connect

鏈接 React 組件與 Redux store。鏈接操做不會改變原來的組件類。反而返回一個新的已與 Redux store 鏈接的組件類。

1.mapStateToProps
若是定義該參數,組件將會監聽 Redux store 的變化。任什麼時候候,只要 Redux store 發生改變,mapStateToProps 函數就會被調用。該回調函數必須返回一個純對象,這個對象會與組件的 props 合併。若是你省略了這個參數,你的組件將不會監聽 Redux store。若是指定了該回調函數中的第二個參數 ownProps,則該參數的值爲傳遞到組件的 props,並且只要組件接收到新的 props,mapStateToProps 也會被調用(例如,當 props 接收到來自父組件一個小小的改動,那麼你所使用的 ownProps 參數,mapStateToProps 都會被從新計算)

// 把state上的todos綁定到 組件.props.todos
function mapStateToProps(state) {
  return { todos: state.todos }
}

export default connect(mapStateToProps)(TodoApp)

2.mapDispatchToProps
(Object or Function): 若是傳遞的是一個對象,那麼每一個定義在該對象的函數都將被看成 Redux action creator,並且這個對象會與 Redux store 綁定在一塊兒,其中所定義的方法名將做爲屬性名,合併到組件的 props 中。若是傳遞的是一個函數,該函數將接收一個 dispatch 函數,而後由你來決定如何返回一個對象,這個對象經過 dispatch 函數與 action creator 以某種方式綁定在一塊兒(提示:你也許會用到 Redux 的輔助函數 bindActionCreators())。若是你省略這個 mapDispatchToProps 參數,默認狀況下,dispatch 會注入到你的組件 props 中。若是指定了該回調函數中第二個參數 ownProps,該參數的值爲傳遞到組件的 props,並且只要組件接收到新 props,mapDispatchToProps 也會被調用。

export function mapDispatchToProps(dispatch) {
  return bindActionCreators(actionCreators, dispatch);
}

// 下面兩種方式效果一致
var App = connect(mapStateToProps, actionCreators)(Main);
var App = connect(mapStateToProps, mapDispatchToProps)(Main);

Provider

包裹Provider讓全部container都能訪問store

store.dispatch(action)

store.dispath(action)會執行reducer(currentState, action)並return action。原生的dipatch只支持普通js對象來做爲參數,不然會報錯。

redux middleware

它提供的是位於 action 被髮起以後,到達 reducer 以前的擴展點。(?)
其實就是在dispatch先後作一些額外的事情的一個函數,這個函數就是middleware, 有多個middlewares也就是嵌套地執行這多個函數。

const logger = ({ dispatch, getState }) => next => action => {
  console.log('dispatching', action)
  let result = next(action)
  console.log('next state', getState())
  return result
}


export default function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, preloadedState, enhancer) => {
    const store = createStore(reducer, preloadedState, enhancer)
    let dispatch = store.dispatch
    let chain = []

    const middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    }
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

const middlewares = [logger]

const store = createStore(
  reducer,
  applyMiddleware(...middlewares)
)

redux thunk

經過redux middleware實現支持dispatch一個函數。

function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }

    return next(action);
  };
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

stackoverflow上的介紹。
容器組件和展現組件相分離

相關文章
相關標籤/搜索