【发布时间】:2020-09-29 16:30:10
【问题描述】:
我的一个 react-redux 组件在状态更改后没有重新渲染。我希望在选中复选框后启用选择。但这不会发生。只有当我在另一个触发重新渲染的组件上单击页面上的其他位置时,一切都会按我的预期进行。我究竟做错了什么?如果有任何帮助,我将不胜感激。
class Select extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<input type="checkbox" onClick={this.props.toggleSelect}/>
<select disabled={ !Object.keys(this.props.syncObjects).includes("select") }>
// some options
</select>
</div>
)
}
}
const mapDispatchToProps = {
toggleSelect
}
const mapStateToProps = state => {
return {
syncObjects: state.json.objects
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Select);
// reducer file
const initialState = {
objects: {}
}
export const myReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_SELECT:
if (Object.keys(state.objects).includes("select")){
const new_state = {...state}
delete new_state.objects["select"]
return new_state
}
else {
return {
...state,
objects: {
...state.objects,
'select': ''
}
}
}
default:
return state
}
}
// actions.js
export function toggleSelect() {
return {
type: TOGGLE_SELECT
}
}
【问题讨论】:
-
问题是你的reducer正在改变状态,你不应该这样做并且导致这个问题。你的
new_state只是一个浅拷贝,然后你改变它的一个子对象。 -
首先,您似乎没有在您的
mapDispatchToProps()中分派任何东西,接下来,您使用delete运算符来改变你的商店,这是为 Redux 静默完成的,因此 React 不会触发重新渲染。请考虑使用不可变技术来过滤掉对象中的属性。 -
我正要开始回答以说明如何解决这个问题,但后来我注意到还有一些奇怪的地方:您的
mapStateToProps引用state.json.objects和render方法关心它是否包含select键与否,但您的减速器仅在state.objects内操作该键。哪个是正确的? -
@yevgengorbunkov 我相信将
mapDispatchToProps定义为对象将自动调度相关操作,因此该部分看起来不错。你对突变当然是正确的。 -
@Helen :显然,您的问题是由使用
delete运算符引起的
标签: javascript reactjs redux react-redux