1. 程式人生 > >react-redux 中state改變,頁面未重新渲染

react-redux 中state改變,頁面未重新渲染

1.問題?

在redux中,通過reducer來對state的進行更新,但是我在reducer中改變了state的值,但是頁面沒有重新渲染,並且在控制檯輸出顯示state的值已經改變

程式碼:

const initStore = [
    {
        name: 'lili',
        blogTitle: 'nihao',
        blogContent: 'nihao',
        nowTime: '2016-4-10'
    },
    {
        name: 'bob',
        blogTitle: '你好!',
        blogContent: '你好!'
, nowTime: '2016-5-15' } ]; export default function (state = initStore, action) { switch (action.type) { case 'DELETE': state.splice(action.index,1); console.log('state:',state);//輸出state的值已經改變 return state; } }

在這裡我在頁面顯示了initStore中的兩條內容,刪除一條,但頁面沒有並沒有重新渲染

2.原因

reducer 就是一個純函式,接收舊的 state 和 action,返回新的 state。保持 reducer 純淨非常重要。

永遠不要在 reducer 裡做這些操作:

修改傳入引數;
執行有副作用的操作,如 API 請求和路由跳轉;
呼叫非純函式,如 Date.now() 或 Math.random()。

Store 會把兩個引數傳入 reducer: 當前的 state 和 action,所以不能直接修改state,redux會比較新舊state的值,直接修改state會導致store內部的也發生改變,那麼新舊state也就沒有發生變化。頁面就不會重新渲染。

3.解決方法

  • 不要修改 state。 使用Object.assign()新建了一個副本。

例子

function todoApp(state = initialState, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      })
    default:
      return state
  }
}
  • 也可以使用 ES7 中還在試驗階段的特性 { ...state, ...newState },參考 物件展開語法。

修改後的程式碼:

export default function (state = initStore, action) {
    switch (action.type) {
        case 'DELETE':
            state.splice(action.index,1);
            return [...state];
    }
}

參考內容