这是一个小型 React 应用程序,它使用 State 并将更新的数据保存到 localStorage。 您可以通过输入名称并按添加按钮来创建按钮。
现在localStorage更新的地方有两点:
addButtonList 函数,第 52 行。该函数在单击“添加”按钮时运行。它还设置按钮列表的状态。
在 if / else 语句中,第 23 行(已注释掉)
在第 1 点更新总是很晚,而第 2 点则工作正常。
我无法在 Codesandbox 中看到 localStorage,但如果您刷新应用程序, 您将看到已创建的按钮已显示,但您最后创建的按钮除外。
所以我的问题是,在这样的应用程序中存储状态数据的正确方法是什么?第2点可以吗?我发现一篇文章建议使用 useEffect 来处理最新数据。
引用文档:
每个 React 组件都经历相同的生命周期:
- 组件添加到屏幕后就会安装。
- 组件在收到新的 props 或状态时更新,通常是为了响应交互。
- 组件从屏幕上移除后就会卸载。
现在您可以发现在应用程序中序列化或存储状态的最理想事件是什么。
安装 - 绝对不
更新 - 如果您的应用程序需要非常高的数据可用性,从某种意义上说,即使是在应用程序发生不可预见和不幸崩溃的情况下,甚至最新的状态更新也可用。
然而,卸载可能是性能和数据可用性之间最平衡的选项。请注意,在这种情况下,数据只会序列化一次 - 在组件卸载期间。
现在要实现同样的功能,useEffect 是 React 提供的一个出色的逃生口。如您所知,localStorage 没有映射到 React。每当我们遇到 React 中无法提供的东西时,我们就需要退出 React。 useEffect 钩子就是做到这一点的方法。它只是为了提供同步两个系统的代码 - 当然一个是 React,另一个可能是像 localStorage 这样的非 React 系统。
因此,下面的示例代码可以完成我们一直在讨论的工作。
请注意,作为其依赖项给出的空数组意味着挂钩内的代码将在安装和卸载应用程序时调用。状态更新时不会调用它。
useEffect(() => {
if (buttonlist.lenghth == 0) {
// the app has just been mounted.
// therefore check the local store,
// and load the state from it.
let newToDoObject = localStorage.getItem('ButtonList');
if (newToDoObject) {
setButtonList(JSON.parse(newToDoObject));
}
} else {
// the app has some state to serialise,
// therefore it means it is in unmount state now,
// so serialise the state here.
localStorage.setItem('ButtonList', JSON.stringify(buttonlist));
}
}, []);