1.问题?
在redux中,通过reducer来对state的进行更新,但是我在reducer中改变了state的值,但是页面没有重新渲染,并且在控制台输出显示state的值已经改变
1
代码:
const defaultState = {
count: 0,
help: '123s',
};
const count = (state = defaultState, action) => { // 同学们可以使用count来实现一个计数器以巩固知识。
switch (action.type) {
case 'ADD':
state.count += 1;
return state;
case 'REDUCE':
state.count -= 1;
return state;
default:
return state;
}
};
在这里我在页面显示了initStore中的两条内容,删除一条,但页面没有并没有重新渲染
2.原因
reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。保持 reducer 纯净非常重要。
1
永远不要在 reducer 里做这些操作:
修改传入参数;
执行有副作用的操作,如 API 请求和路由跳转;
调用非纯函数,如 Date.now() 或 Math.random()。
Store 会把两个参数传入 reducer: 当前的 state 和 action,所以不能直接修改state,redux会比较新旧state的值,直接修改state会导致store内部的也发生改变,那么新旧state也就没有发生变化。页面就不会重新渲染。
3.解决方法
不要修改 state。 使用Object.assign()新建了一个副本。
例子
const defaultState = {
count: 0,
help: '123s',
};
const count = (state = defaultState, action) => { // 同学们可以使用count来实现一个计数器以巩固知识。
switch (action.type) {
case 'ADD':
return assgin({}, state, {
count: state.count + 1,
});
case 'REDUCE':
return assgin({}, state, {
count: state.count - 1,
});
default:
return state;
}
};
也可以使用 ES7 中还在试验阶段的特性 { ...state, ...newState },参考 对象展开语法。
修改后的代码:
export default function (state = initStore, action) {
switch (action.type) {
case 'DELETE':
state.splice(action.index,1);
return [...state];
}
}