React 功能组件不会根据自己的状态变化重新渲染

时间:2021-02-21 15:23:35

标签: javascript reactjs react-hooks

所以我在网上找到了一个叫做 useStickyState 的钩子,并一直试图将它实现到我的 React 应用程序中。

我遇到的问题是,当我尝试更新 useStickyState 钩子的状态时,它实际上并没有更新本地存储或重新渲染声明状态的组件。当更新不同的状态导致组件重新渲染时,它似乎只会更新 localstorage。

当我从子组件运行 setHelpText() 时,控制台会注册“get item”和“set item”以及“render app container”。

但是,如果我从子进程运行 setMasterText(),AppContainer 根本不会重新渲染。

我能想到的唯一区别是 setHelpText 接收一个字符串,例如setHelpText("废话废话").

而 setMasterText 接收更新的对象数组,其中只更改了数组项的现有属性(而不是数组项的数量)。

AppContainer.js

import React, { useState } from "react";
import { useStickyState } from "../../hooks/useStickyState";
import "./AppContainer.scss";

//COMPONENTS
import HelpText from "../HelpText/HelpText";
import EditArea from "../EditArea/EditArea";

//DATA
import { HelpTextData } from "../../data/HelpTextData";

const AppContainer = () => {
  const [masterText, setMasterText] = useStickyState([], "mastertext");
  const [helpText, setHelpText] = useState(HelpTextData.welcome);

  console.log("render app container");

  return (
    <div id="app-container">
      <HelpText text={helpText} />
      <EditArea
        masterText={masterText}
        setMasterText={setMasterText}
        setHelpText={setHelpText}
      />
    </div>
  );
};

export default AppContainer;

从 AppContainer 的子项更改 helpText 状态的示例:

// Previous state
helpText = "abc";

// Setting new state
setHelpText("cde");

// Re-render triggered

从 AppContainer 的子级更改 masterText 状态的示例:

// Previous state
masterText = [
  {
    words: [
             {text: "hello", selected: true},
             {text: "there", selected: false}
           ]
  },
  {
    words: [
             {text: "Hi", selected: false},
             {text: "there", selected: false}
           ]
  },
]

// Setting new state
let newMasterText = masterText;
newMasterText[0].words[0].text = "Abc";

setMasterText(newMasterText);

// No re-render triggered

useStickyState.js

import React from "react";

export function useStickyState(defaultValue, key) {
  const [value, setValue] = React.useState(() => {
    const stickyValue = window.localStorage.getItem(key);
    console.log("get item");
    return stickyValue !== null ? JSON.parse(stickyValue) : defaultValue;
  });
  React.useEffect(() => {
    console.log("set item");
    window.localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);
  return [value, setValue];
}

1 个答案:

答案 0 :(得分:0)

所以我想我已经想通了!

对于任何有类似问题的人:

我已经放弃使用自定义挂钩。相反,我传递了一个句柄函数,而不是直接传递 setMasterText 函数。这意味着我可以保证在需要更新状态时保存到本地存储。

请看下面:

const handleMasterTextUpdate = (newMasterText) => {
    localStorage.setItem("mastertext", JSON.stringify(newMasterText));
    setMasterText(newMasterText);
  };