javascript - React 组件在加载时“闪烁”,因为状态被覆盖
问题描述
我使用 React 开发了一个待办事项应用程序,事情变得更加清晰,但我很难理解“生命周期”。在 VueJS 中,我知道一个ComponentDidMount()
钩子,如果我猜它会帮助我解决这个问题,但在 React 中我找不到它。
我有一系列这样的待办事项:const todos = [{description: "walk dog", done: false}]
这是我的应用程序的初始状态:
const [alltodos, handleTodos] = useState([]);
在加载时,我使用这个useEffect
钩子从 localStorage 获取数据。
useEffect(() => {
const items = localStorage.getItem("todos");
const parsed = JSON.parse(items);
handleTodos(parsed);
}, []);
我用这个函数计算我的待办事项:
const countTodos = () => {
const donetodos = alltodos.filter((item) => {
return !item.done;
});
countOpen(donetodos.length);
};
如果依赖项发生变化,我会更新计数:
useEffect(() => {
countTodos();
localStorage.setItem("todos", JSON.stringify(alltodos));
}, [alltodos]);
所以会发生什么,计数器从 0 开始,然后“闪烁”一毫秒,然后显示我从本地存储中获得的待办事项数量。
有没有办法防止这种行为?据我所知,组件首先呈现,然后触发 useEffect 挂钩。从本地存储中提取数据后如何渲染组件?
解决方案
用初始化allTodos
状态null
。只要这个状态是null
,渲染一个通知或者只是返回null
什么都不渲染。
您可以直接从当前alltodos
状态计算打开的待办事项计数,而无需useEffect
.
const [alltodos, handleTodos] = useState(null);
useEffect(() => {
const items = localStorage.getItem("todos");
const parsed = items ? JSON.parse(items) : [];
handleTodos(parsed);
}, []);
useEffect(() => {
localStorage.setItem("todos", JSON.stringify(alltodos));
}, [alltodos]);
if(alltodos === null) return 'Loading todos list';
// this is derived from state, so you don't have to create a state for it
const openTodosCount = alltodos.reduce((acc, o) => acc + !o.done, 0);
推荐阅读
- c# - c# 中的不可变局部值 - 一个特定用例
- typo3 - 动态元素
- c++ - 如何在另一个字符串c ++中的最后一个反斜杠之后添加一个字符串
- r - 如何使用 ggsignif 包将 p 值添加到堆积条形图?
- ubuntu - nvidia-smi 和 nvidia x 服务器设置之间的顺序不同
- logback - 是否可以使用 logback.xml 从 ch.qos.logback 配置日志消息?
- windows - 用于在多个目录中创建相同文件夹的 PowerShell 脚本
- node.js - HTTP POST Firebase 云函数“Access-Control-Allow-Origin”错误
- .net - Convert XDocument to string without added /r /n
- login - Blue Prism - 输入文本框登录名和密码,但网站显示请输入用户名和密码