【问题标题】:How to render a React functional component when useState() changes?当 useState() 改变时如何渲染 React 功能组件?
【发布时间】:2021-04-21 20:34:57
【问题描述】:

我有一个非常简单的功能组件,它从 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 组件会容易得多,但我也想学习函数式组件。我在这里错过了什么?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您似乎希望 setFocusDate 是同步的,wich is not the case。因此,如果您调用 setFocusDate 并在此之后(下一行)使用 focusDate 更新本地存储,您不能期望本地存储包含新的 focusDate 值。例如,您可以阅读此here

    在您的示例中,我怀疑本地存储更新是使用先前的状态值完成的,因为 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/

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2021-01-14
        • 2016-08-28
        • 2022-12-23
        • 1970-01-01
        • 1970-01-01
        • 2021-11-26
        • 2022-01-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多