我有一个firebase
项目,其中一个firestore
database
document
看起来像这样。
document-id =>
item1 => {detail: "value", title: "value", image: "value}
item2 => {detail: "value", title: "value", image: "value}
...
我呈现此效果的React component
看起来像这样:
const [data, setData] = useState({});
useEffect(() => {
firebase.getDocument("path-to-document").then(section => {
if (section) {
setPanels(section.data());
}
});
}, []);
const handleChange = (id, data) => {
const payload = data;
payload[id] = { ...panels[id], ...data };
setData(payload);
}
return (<div>
{Object.keys(data).map((key) => <Card
data={data[key]}
onChange={handleChange} />)}
</div>);
我已从中删除了多余的代码,但是Card
组件可以简单地设置各个对象的布局。更改后,它将正确调用handleChange
函数,并且data State
被正确更新为新值(在console.log(data)
方法调用显示此之后,调用setData
)。但是component
不会reRender
带有data
的新值。
是否有某种方法可以强制重新渲染组件?我在网上其他地方发现,如果调用setData的数据与当前使用的数据相同,即React
会“重投”,即不进行任何实际更改。
或者相反,还有另一种方式来处理此交互并让Card
组件处理数据的持久性吗?
谢谢。
答案 0 :(得分:3)
尝试设置您的有效载荷的副本:{...payload}
:
const handleChange = (id, data) => {
const payload = data;
payload[id] = { ...panels[id], ...data };
setData({...payload});
}
因为您没有更改状态,所以您的应用程序不会反应并重新呈现。
在 React Docs 上签出Functional Updates。
const handleChange = (id, data) => {
const payload = data;
payload[id] = { ...panels[id], ...data };
setData(prevPayload => {
console.log(prevPayload === payload) // true
return payload // No Re-Render
// console.log(prevPayload === { ... payload }) // false
// return { ... payload } // Re-render
);
}
在codesandbox上浏览此示例。