在ViewDispatcher
组件中,我使用react-use库中的useList
钩子获取输入属性initialItems
并创建items
变量。这有助于我使用update
方法轻松地操作列表:
export const ViewDispatcher = ({ mode, loading, items: initialItems }) => {
const [items, { update }] = useList(initialItems);
console.log("[ViewDispatcher] Rendering", initialItems, items);
switch (mode) {
case "list":
if (loading) {
return null;
}
return <>{JSON.stringify(items)}</>;
default:
throw new Error("Unsupported view.");
}
};
我面临的问题(pen here)是:**为什么我的items
变量为空,而initialItems
被正确填充?**我禁用了React strict模式以避免污染日志:
[视图调度程序]呈现[] []
[ViewDispatcher]呈现[对象,对象,对象,对象,对象,对象,对象,对象,对象,...] []
输入items
来自View
组件,该组件只是从
export const View = () => {
const [{ loading, items }, setState] = useState({ loading: true, items: [] });
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/todos")
.then((res) => res.json())
.then((items) => {
setState((prev) => ({ ...prev, loading: false, items }));
});
}, []);
return <ViewDispatcher mode="list" loading={loading} items={items} />;
};
1条答案
按热度按时间tvokkenx1#
React会保存初始状态一次,并在下次渲染时忽略它,这样做的任何操作都将被忽略:
1.通过props更新初始状态:
在第一次呈现时,
ViewDispatcher
从项中接收[]
,并因此设置initialState,在由属性更改引起的后续呈现时,来自items
的新值将被忽略。2.重新创建初始状态:
在第一次呈现时,状态由
createInitialStateFn()
初始化一次,在后续呈现时,将忽略从createInitialStateFn()
返回的任何内容。要解决此问题
您可以将
useList
提升到父组件,并使用useList
库中的update
函数更新状态,就像dot then块中的setState((prev) => ({ ...prev, loading: false, items }));
一样。您可能需要正确地重构状态:
父组件和子组件都保持
items
状态,很有可能可以将这两个状态合并为一个状态,否则,每次状态更改时,都必须使用setter
同时更新这两个状态,以便保持它们同步。而创建一个独立的加载状态特别是最适合你的情况我想: