为什么在下面的伪代码示例中,当容器更改foo.bar时,子不重新呈现?
Container {
handleEvent() {
this.props.foo.bar = 123
},
render() {
return <Child bar={this.props.foo.bar} />
}
Child {
render() {
return <div>{this.props.bar}</div>
}
}
即使我在修改Container中的值后调用forceUpdate(), Child仍然显示旧值。
我有同样的问题的重新渲染对象道具,如果道具是一个对象JSON.stringify(obj),并将其设置为功能组件的关键。为react钩子设置一个id键对我来说并不适用。奇怪的是,要更新组件,你必须在键上包含所有对象属性并将其连接到那里。
function Child(props) {
const [thing, setThing] = useState(props.something)
return (
<>
<div>{thing.a}</div>
<div>{thing.b}</div>
</>
)
}
...
function Caller() {
const thing = [{a: 1, b: 2}, {a: 3, b: 4}]
thing.map(t => (
<Child key={JSON.stringify(t)} something={thing} />
))
}
现在,任何时候thing对象在运行时改变了它的值,子组件将正确地重新呈现它。
我也有同样的问题。
这是我的解决方案,我不确定这是一个好的实践,如果不是告诉我:
state = {
value: this.props.value
};
componentDidUpdate(prevProps) {
if(prevProps.value !== this.props.value) {
this.setState({value: this.props.value});
}
}
UPD:现在你可以用React Hooks做同样的事情:
(仅当component是函数时)
const [value, setValue] = useState(propName);
// This will launch only if propName value has chaged.
useEffect(() => { setValue(propName) }, [propName]);
在我的例子中,我正在更新传递给组件的加载状态。在按钮内的道具。加载是通过预期的(从假切换为真),但显示旋转器没有更新的三元。
我尝试添加一个键,添加一个状态,更新useEffect()等,但没有其他答案工作。
对我有效的是改变这一点:
setLoading(true);
handleOtherCPUHeavyCode();
:
setLoading(true);
setTimeout(() => { handleOtherCPUHeavyCode() }, 1)
我认为这是因为handleOtherCPUHeavyCode中的进程非常繁重和密集,所以应用程序会冻结一秒钟左右。添加1ms超时允许加载布尔值更新,然后繁重的代码函数可以完成它的工作。