当前位置: 首页 > 知识库问答 >
问题:

当useState()更改时,如何呈现React函数组件?

张建树
2023-03-14

我有一个非常简单的功能组件,它从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月,但是当我在onLefthtml上单击几次时,它并没有呈现组件,尽管我期望它显示2021年12月。计算是正确的,我想我在这里丢失了功能组件渲染的概念。对于Class组件来说,这会容易得多,但我也想学习功能性组件。我错过了什么?

共有2个答案

潘意
2023-03-14

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

const month = new Date(focusDate).getMonth();
const year = ew Date(focusDate).getFullYear();
郤瀚
2023-03-14

似乎您希望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/

 类似资料:
  • 我使用Rails与反应宝石和react-router.js内部资产。我使用webpack为了使用需要 我有我的路线内的应用程序。js: 另外es6。jsx: 当我访问controller_name/index时,默认情况下,它会呈现带有“#hello”链接的“欢迎组件”文本,但单击时,它不会执行任何操作。它仍然在说“欢迎组件” 我做错了什么?

  • 渲染后,我得到了当前分配给USESTECT常量的值。我已经在useEffect中初始化了常量值,但仍然无法获得结果。

  • 在标记为副本之前,请仔细阅读此内容,我向您保证,我已经阅读并尝试了每个人在stackoverflow和github上提出的关于此问题的所有建议。 我在我的应用程序中有一条路线,如下所示; route rendering呈现打开用户角色的组件,并基于该角色惰性加载正确的Routes组件,Routes组件呈现主页的开关。简化后,如下所示。 然后是路由组件 因此,问题是每当用户从/导航到/秒等...应用

  • 我在一个表单上有一个TextField输入,问题是当我在它上键入时,刚刚键入的值的显示/呈现有一种延迟,我想防止这种延迟。 代码:

  • 我正在学习React钩子,这意味着我将不得不从类转移到函数组件。以前,在类中,我可以拥有与状态无关的类变量,我可以在不重新呈现组件的情况下更新这些变量。现在我试图用钩子重新创建一个组件作为函数组件,我遇到了这样一个问题:我不能(就我所知)为该函数创建变量,因此存储数据的唯一方法是通过钩子。然而,这意味着每当该状态更新时,我的组件将重新呈现。 我已经在下面的示例中说明了这一点,我试图将类组件重新创建

  • 我将2个值传递给子组件: 要显示的对象列表 删除函数。 我使用.map()函数来显示我的对象列表(就像react教程页面中给出的示例),但是该组件中的按钮在呈现时激发函数(它不应该在呈现时激发)。我的代码如下所示: 我的问题是:为什么函数在render时触发,以及如何使它不触发?