Javascript Redux不';不要重新渲染组件
我有一个组件,它从Javascript Redux不';不要重新渲染组件,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我有一个组件,它从mapstatetrops()方法获取数据。组件代码为: handleClick = () => { if (this.props.data.status) { this.props.changeIpStatus(index, !this.props.data.status); } else { this.props.changeIpStatus(index, !this.props
mapstatetrops()
方法获取数据。组件代码为:
handleClick = () => {
if (this.props.data.status) {
this.props.changeIpStatus(index, !this.props.data.status);
} else {
this.props.changeIpStatus(index, !this.props.data.status);
}
}
render() {
if (this.props.data.status) {
this.switchClasses = `switcher blocked`;
this.dotClasses = `dot blocked`;
} else {
this.switchClasses = `switcher`;
this.dotClasses = `dot`;
}
return (
<div className="block">
<div onClick={this.handleClick} className={this.switchClasses}>
<div className={this.dotClasses}></div>
</div>
</div>
)
}
}
当我单击switcher时,它应该重新渲染,因为数据已更改。我通过控制台日志看到数据发生了更改。但它不会调用重新渲染。为什么?我的组件具有mapStateToProps,其中包含更改和操作导入正确(选中)的数据
更新:
这是我的减速机:
const initialState = {
data: {}
}
const ipReducer = (state = initialState, action) => {
switch (action.type) {
case `SET_CLICKS`:
return {
...state,
data: action.data
}
case `CHANGE_IP_STATUS`:
let newState = Object.assign({}, state);
newState.data.clicks[action.index].status = action.status;
return newState;
default: return state;
}
}
export default ipReducer;
问题在于对象的深度复制。在JavaScrip中,为了复制对象而不在它们之间进行任何引用,我们必须使用,例如:
let newState = JSON.parse(JSON.stringify(state));
不是这个:
let newState = Object.assign({}, state); // <-- this is do not return a standalone new object. Do not use it in your reducer.
let newState=Object.assign({},state);// 问题在于对象的深度复制。在JavaScrip中,为了复制对象而不在它们之间进行任何引用,我们必须使用,例如:
let newState = JSON.parse(JSON.stringify(state));
不是这个:
let newState = Object.assign({}, state); // <-- this is do not return a standalone new object. Do not use it in your reducer.
let newState=Object.assign({},state);// 您可以使用JSON.parse(JSON.stringify(…)
方法,但请注意,如果您的状态包含不可序列化的属性,则会丢失它
这里有另一种方法。您可以更频繁地看到此方法
// map the clicks, if index match return the new one with the new status
// if the index does not match just return the current click
const newClicks = state.data.clicks.map((click, index) => {
if (index !== action.index) return click;
return { ...click, status: action.status };
});
// Here, set your new state with your new clicks without mutating the original one
const newState = { ...state, data: { ...state.data, clicks: newClicks } };
return newState;
第二种选择是这样的。不映射所有的点击
我们可以使用对象。为点击
指定
const newClicks = Object.assign([], state.data.clicks, {
[action.index]: { ...state.data.clicks[action.index], status: action.status }
});
const newState = { ...state, data: { ...state.data, clicks: newClicks } };
return newState;
您可以使用JSON.parse(JSON.stringify(…)
方法,但请注意,如果您的状态包含不可序列化的属性,则会丢失它
这里有另一种方法。您可以更频繁地看到此方法
// map the clicks, if index match return the new one with the new status
// if the index does not match just return the current click
const newClicks = state.data.clicks.map((click, index) => {
if (index !== action.index) return click;
return { ...click, status: action.status };
});
// Here, set your new state with your new clicks without mutating the original one
const newState = { ...state, data: { ...state.data, clicks: newClicks } };
return newState;
第二种选择是这样的。不映射所有的点击
我们可以使用对象。为点击
指定
const newClicks = Object.assign([], state.data.clicks, {
[action.index]: { ...state.data.clicks[action.index], status: action.status }
});
const newState = { ...state, data: { ...state.data, clicks: newClicks } };
return newState;
我不是百分之百确定,但我担心您在reducer caseCHANGE\u IP\u STATUS
(Object.assign
不深度克隆对象)中正在改变您的状态,有没有关于如何深度克隆的建议?JSON.parse(JSON.stringify(state))
或从“lodash/deepClone”导入deepClone
如果您提供BlockSwitcher组件的全部代码(可能省略不相关的功能),则调试会更容易。您可以通过console.log看到数据的变化,但是您在哪里编写了console.log()?为了确定数据在其生命周期中是如何处理的(可能是哪里出了问题),这一点非常重要。我不是100%确定,但我担心在这种情况下,您正在改变您的状态CHANGE\u IP\u STATUS
(Object.assign
不是深度克隆对象)有没有建议如何深度克隆?JSON.parse(JSON.stringify(state))
或从'lodash/deepClone'导入deepClone
如果提供BlockSwitcher组件的整个代码(可能省略不相关的函数),那么调试会更容易。您还可以通过console.log看到数据的变化,但是您在哪里编写了console.log()?为了确定数据在整个生命周期中是如何处理的(以及在哪里出错),这一点非常重要。是否clicks
属性是数组?@devserkan是的,然后让我另一个备选答案。因为如果所有状态属性都不可序列化,则此方法不起作用。您可以使用扩展运算符const newState={…state}
@sridharredy spread操作符将完成深度复制的工作吗?
clicks
属性是数组吗?@devserkan是的,然后让我给出另一个备选答案。因为如果所有状态属性都不可序列化,此方法不起作用。您可以使用spread操作符const newState={…state}
@sridharred spread operator将通过深度复制来完成这项工作?