所以我在网上找到了一个叫做 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];
}
答案 0 :(得分:0)
所以我想我已经想通了!
对于任何有类似问题的人:
我已经放弃使用自定义挂钩。相反,我传递了一个句柄函数,而不是直接传递 setMasterText 函数。这意味着我可以保证在需要更新状态时保存到本地存储。
请看下面:
const handleMasterTextUpdate = (newMasterText) => {
localStorage.setItem("mastertext", JSON.stringify(newMasterText));
setMasterText(newMasterText);
};