問題:在使用redux/react-redux中,reducer的數據明明已經更改了,但是卻不能觸發組件的render函數,頁面也沒有同步更新
reducer代碼如下:
import { ADDTODO, DELETETODO, UPDATETODO, CLEARTODO, CHECKAllTODO } from './constant' const initState = [ { id: '001', task: '唱歌', done: false }, { id: '002', task: '跳舞', done: false }, { id: '003', task: '打球', done: false }, ]; export default function todoReducer(preState = initState, action) { const { type, data } = action; switch (type) { case ADDTODO: preState.push(data) return preState; case DELETETODO: return preState.filter(v => v.id !== data) case UPDATETODO: return preState.map(v => { if (v.id === data) v.done = !v.done; return v }) case CLEARTODO: return preState.filter(v => !v.done); case CHECKAllTODO: return preState.map(v => ({ ...v, done: data })); default: return preState; } }
原因分析:
reducer是一個純函數,不能修改參數preState,並且當你返回preState時,redux/react-redux並不知道數據已經更改(preState是對象引用,始終指向一個地址),而這里對preState進行了push操作,並把操作后的preState返回。
解決辦法:
reducer代碼如下:
import { ADDTODO, DELETETODO, UPDATETODO, CLEARTODO, CHECKAllTODO } from './constant' const initState = [ { id: '001', task: '唱歌', done: false }, { id: '002', task: '跳舞', done: false }, { id: '003', task: '打球', done: false }, ]; export default function todoReducer(preState = initState, action) { const { type, data } = action; switch (type) { case ADDTODO: return [...preState, data]; case DELETETODO: return preState.filter(v => v.id !== data) case UPDATETODO: return preState.map(v => { if (v.id === data) v.done = !v.done; return v }) case CLEARTODO: return preState.filter(v => !v.done); case CHECKAllTODO: return preState.map(v => ({ ...v, done: data })); default: return preState; } }