尝试使用 useContext 值设置状态

Trying to set state using useContext values

您好,我正在创建一个 gatsby React 应用程序,我在此页面上的主要目标是删除一些 localStorage 并在渲染后重置上下文。 AFTER 很重要,因为我希望我的页面呈现一些数据,但呈现后,我想删除该数据。 (为了保持持久状态,我在 localStorage 中有一些数据)

  1. 这可能吗?

  2. 我的第一次尝试是这样的:

    • 对于这个代码片段,如果我注释掉 useEffect 会出现我的组件,这是有道理的,但是当我添加 useEffect 时它不会呈现我的组件,这是预期的但不是我想要的:(
const {data, setData} = useContext(context)

useEffect(() => {
  console.log('deleting');
  setData({});
  localStorage.removeItem('data');
}, []);


const components = [];
for (const item in data) {
    if ({}.hasOwnProperty.call(data, item)) {
      const { dataItem } = data[item];
      components.push(<Component dataItem={dataItem} />);
    }
  }


return (
   <div>
     {components}
   <div>
);
  1. 我的第二次尝试有点相似,不同之处在于我尝试将数据保存到 localState 中以查看是否允许它在被删除后仍然存在并且我不再获取子组件中的上下文,相反,我在父组件中获取它并将其作为 prop 传递给子组件:
    • 这里的问题是我的 localData 始终是一个空对象。但是我的控制台语句显示 data 实际上有数据,但是当我使用 State(data) 时,我的 localData 始终是一个空对象。即使我使用状态({})然后我设置本地数据(数据)我得到一个无限循环:(
console.log(data);
const [localData, setlocalData] = useState(data); //this is the same data as in the other snippet
console.log(localCartInfo);

// rest of the code is the same except im now replacing data with localdata

如果任何知道 React 实际工作原理的人可以帮助我,将不胜感激。

好的,所以你想在渲染后执行一个动作。好吧,这很老套,但可以使用简单的技巧来完成,这是一个有效的例子:

https://codesandbox.io/s/boring-wood-wxmtq?file=/src/App.js

尝试创建本地状态并在删除数据之前将数据保存在其中。

然后渲染那个本地状态。

const {data, setData} = useContext(context);
const [value] = useState(data); // initialize on mount with the context value. No need to change that value later on

useEffect(() => {
  console.log('deleting');
  setData({});
  localStorage.removeItem('data');
}, []);


const components = [];
for (const item in value) { // here, read value instead of data
    if ({}.hasOwnProperty.call(data, item)) {
      const { dataItem } = data[item];
      components.push(<Component dataItem={dataItem} />);
    }
  }


return (
   <div>
     {components}
   </div>
);

我最终通过在第一页加载时将上下文数据保存到 cookie 中解决了这个问题。 这比设置 localState 效果更好,因为它不需要重新加载组件来设置 cookie,并且由于有可能使其过期,因此无论如何 cookie 对我的用例来说效果更好。

我是这样做的:

let localData = {};

const {data, setData} = useContext(dataContext);

if (Object.keys(data).length > 0) {
      // create cookie with existing data before it gets deleted
      const cookieString = `localData=${JSON.stringify(data)}`;
      document.cookie = cookieString;
      localData = data;
    } else {
      // if data doesn't exist, get the data from the localData cookie
      localData = JSON.parse(document.cookie.substring(10));
    }