Redux 生產實踐使用注意事項

背景:在我們使用 React 時,通常都是和 Redux 配合使用,Redux 管理數據狀態,去控制 DOM 的渲染與更新。

在使用 Redux 的時候,有一些注意的地方,否則可能出現意料之外的情況,卻不知道原因是什麼,其中有一點就是下面這個例子:

/**
 * action-reducer.js
 * @param {*} uid 
 */

const getUid = (uid) => ({type: GET_UID}, uid);

const initialState = {
  uid: ""
};

const userInfo = (state = initialState, action) => {
  switch (action.type) {
    case GET_UID:
      return Object.assign({}, state, {uid: action.uid});
    default:
      return state;
  }
}

export default userInfo;
export {getUid};

/**
 * 組件
 */

function mapStateToProps(state) {
  return {uid: state.userInfo.uid}
}

代碼分了兩段,上面那段是我爲了簡單,將 action 和 reducer 合併成一個文件了,export 出一個 getUid 的函數,每次 dispatch 這個函數會將一個 uid 傳入進去,更新 reducer userInfo state 的 uid。組件中 state 和組件通過 mapStateToProps 函數進行了綁定,這樣每次dispatch(getUid()) 更新 state 後將會重新渲染組件。

但是,這樣的寫法是有問題的哦

現在這個寫法,多次 dispatch(getUid()) 假如傳入的是同一個 uid,render() 是不會重新渲染的。問題出在哪裏?出在這裏:

function mapStateToProps(state) {
  return {uid: state.userInfo.uid}
}

mapStateToProps 的時候將 userInfo 中的 uid 提取出來進行了重新賦值,這樣只要 uid 沒有變化的話,對於 Redux 來說,state 是沒有更新的,所以就不會重新渲染了,如果我們想要做到重新渲染的話,就要用下面的寫法:

function mapStateToProps(state) {
  return {userInfo: state.userInfo}
}

然後使用 this.props.userInfo.uid 來獲取 uid,這樣就可以更新組件了,即使 uid 是相同的哦。原因是:

case GET_UID:
    return Object.assign({}, state, {uid: action.uid});

每次 dispatch 時,都會通過 Object.assign() 生成一個新的對象,這樣對於 state 來說,每次對象的引用是不同的,進行 diff 比較時,就會認爲 state 是更新的,響應的組件就執行 render()。

OK,這次的注意事項就到這裏!歡迎討論!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章