React功能组件在自己的状态改变时不重新渲染



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

我遇到的问题是,当我试图更新useStickyState钩子的状态时,它实际上并没有更新本地存储或重新呈现声明状态的组件。只有当一个不同的状态被更新导致组件重新渲染时,它才会真正更新本地存储。

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

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

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

而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];
}

我想我已经弄明白了!

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

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

请参见下文:

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

最新更新