如何呈现一个React功能组件时,useState()的变化?



我有一个非常简单的功能组件,它从localStorage获取日期并显示它。我有两个按钮,从日期添加或删除周,我希望新的日期显示。但是,组件不会被渲染。

import React, { useState } from "react";
import { monthList } from "../common/lists";
const Navbar = () => {
const [focusDate, setFocusDate] = useState(
Number(localStorage.getItem("focusDate"))
);
const [month] = useState(new Date(focusDate).getMonth());
const [year] = useState(new Date(focusDate).getFullYear());
const onLeftClick = () => {
setFocusDate(focusDate - 504000000); //one week
localStorage.setItem("focusDate", focusDate);
};
const onRightClick = () => {
setFocusDate(focusDate + 504000000);
localStorage.setItem("focusDate", focusDate);
};
return (
<div className="navbar-container">
<div className="calendar-navigation-container">
<div className="navbar-menu-item">
<i onClick={onLeftClick} className="fas fa-chevron-left"></i>
</div>
<div onClick={onRightClick} className="navbar-menu-item">
<i className="fas fa-chevron-right"></i>
</div>
<div className="calendar-year">{`${monthList[month]} ${year}`}</div>
</div>
</div>
);
};

该组件的预期行为是获取时间戳,然后显示该时间戳的月份和年份。加载后,它正确显示2021年1月,但是当我在onLeftClick上单击几次时,它不会渲染组件,尽管我期待它显示2021年12月。计算是正确的,我想我在这里遗漏了功能组件渲染的概念。使用Class组件会容易得多,但我也想学习函数式组件。我遗漏了什么?

似乎您期望setFocusDate是同步的,但事实并非如此。因此,如果你调用setFocusDate并在那之后(下一行)用focusDate更新本地存储,你不能期望本地存储包含新的focusDate值。例如,你可以在这里阅读。

在你的例子中,我怀疑本地存储更新是用以前的状态值完成的,因为setFocusDate是计划的,但尚未由React执行。

如果你想更新本地存储与状态(同步状态与本地存储),那么你必须使用useEffect挂钩,与focusDate在依赖关系数组(第二个参数为useEffect,所以当focusDate改变,useEffect被触发)。:

useEffect(() => {
// this function will be called after focusDate changed
// update local storage here
}, [focusDate]);

除此之外,您还可以使用一个专用的钩子来同步本地存储与组件状态,如下所示:https://usehooks.com/useLocalStorage/

您不需要使月和年变量成为状态的一部分,因为它们的值只计算一次。只要断言就足够了

const month = new Date(focusDate).getMonth();
const year = ew Date(focusDate).getFullYear();

最新更新