我的主应用带有两个子组件,两个子组件都具有相同的model
属性。
第一个子组件处理model.myNumberProperty
中的数字道具,第二个子组件处理model.myArrayProperty
中的数字道具
在子组件1中更改model.myNumberProperty
会触发重新渲染,但是
不能更改子组件2中的model.myArrayProperty
function App() {
const model = MyModel();
return (
<div className="App">
Main app
<ComponentOne dataObject={model} />
<ComponentTwo dataObject={model} />
</div>
);
}
export default function MyModel() {
let _propOne = 0;
let _propTwo = ["one"];
const propOne = () => {
return _propOne;
};
const propTwo = () => {
return _propTwo;
};
const modifyPropOne = () => {
_propOne++;
console.log("modifying prop one", _propOne);
};
const modifyPropTwo = () => {
_propTwo.push("new element");
};
return Object.freeze({ propOne, propTwo, modifyPropOne, modifyPropTwo });
}
const ComponentOne = props => {
const [propOne, setPropOne] = useState(props.dataObject.propOne());
const onButtonOneClick = () => {
props.dataObject.modifyPropOne();
setPropOne(props.dataObject.propOne());
};
return (
<div>
<p>Hello ComponentOne:</p>
<button onClick={onButtonOneClick}>ModifyPropOne</button>
<p>{propOne}</p>
</div>
);
};
const ComponentTwo = props => {
const [propTwo, setPropTwo] = useState(props.dataObject.propTwo());
const onButtonTwoClick = () => {
props.dataObject.modifyPropTwo();
setPropTwo([...props.dataObject.propTwo()]);
console.log('Prop two', props.dataObject.propTwo());
};
return (
<div>
<p>Hello ComponentTwo</p>
<button onClick={onButtonTwoClick}>ModifyPropTwo</button>
{propTwo.map((value, index) => (
<p key={index}>{value}</p>
))}
</div>
);
};
请查看this CodeSandbox进行测试。
我正在使用React Hooks。 解决我的问题的方法只能是React,所以不能使用Redux或其他第三方库。
请注意,我的模型是冻结对象以执行封装,因此我不能只是重新创建整个对象。该示例中的模型是简化后的模型,在我的真实项目中,它是一个复杂的Card游戏对象,可以处理许多数组。
答案 0 :(得分:2)
在调用setState
时,React使shallow comparison处于先前的状态,并决定是否应继续进行渲染阶段。
在您的情况下,它具有相同的引用,因此不会触发渲染。
要修复此问题,请将阵列的副本设置为新状态。
const onButtonTwoClick = () => {
props.dataObject.modifyPropTwo();
// v Make a new copy.
setPropTwo([...props.dataObject.propTwo()]);
};