Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在Reactjs中创建可撤销的横幅组件?_Javascript_Reactjs - Fatal编程技术网

Javascript 如何在Reactjs中创建可撤销的横幅组件?

Javascript 如何在Reactjs中创建可撤销的横幅组件?,javascript,reactjs,Javascript,Reactjs,我正在尝试使用react的createContext创建一个横幅组件,该组件将在上下文状态下呈现。我已将状态和设置状态传递给上下文,将允许用户更改上下文状态。我将此上下文状态存储在localStorage中,它允许在网站关闭后预先列出上下文 但我的背景一直在不停地重播。 这是我的bannerContext代码 import React, { useState, useContext, createContext, useEffect } from "react"; cons

我正在尝试使用react的createContext创建一个横幅组件,该组件将在上下文状态下呈现。我已将状态和设置状态传递给上下文,将允许用户更改上下文状态。我将此上下文状态存储在localStorage中,它允许在网站关闭后预先列出上下文

但我的背景一直在不停地重播。 这是我的bannerContext代码

import React, { useState, useContext, createContext, useEffect } from "react";

const BannerContext = createContext({});

export const BannerProvider = ({ children }) => {
  const [banner, setbanner] = useState(false);

  useEffect(() => {
      setbanner(() => {
        const bannerState = window.localStorage.getItem("bannerState");
        return bannerState !== null ? JSON.parse(bannerState) : true;
      });
      window.localStorage.setItem("bannerState", banner);
 
  }, [banner]);
  return (
    <BannerContext.Provider value={{ banner, setbanner }}>
      {children}
    </BannerContext.Provider>
  );
};

export const useBanner = () => useContext(BannerContext);
import React,{useState,useContext,createContext,useffect}来自“React”;
const BannerContext=createContext({});
导出const BannerProvider=({childrend})=>{
const[banner,setbanner]=useState(false);
useffect(()=>{
退刀盘(()=>{
const bannerState=window.localStorage.getItem(“bannerState”);
return bannerState!==null?JSON.parse(bannerState):true;
});
window.localStorage.setItem(“banner状态”,banner);
},[横幅];
返回(
{儿童}
);
};
导出常量useBanner=()=>useContext(BannerContext);
如何避免重新加载,并且仍然使用本地存储进行检查。

问题 其效果是更新其依赖项数组中的值,即
横幅
,因此此代码将呈现循环

解决方案 我认为效果中的
setBanner
是不必要的。如果我了解您的代码的用途,您希望某个组件从上下文调用
setBanner
,并希望此
useffect
将新的
横幅
值保存到本地存储

  • 当组件装载时,从本地存储器获取初始的
    标题
    状态。看
  • 使用
    useffect
    hook仅将
    banner
    状态更新持久化到本地存储
  • 代码:


    在“使用效果”中修改状态值不是一个好主意。如果处理不当,将触发连续重新渲染。我得到您的解决方案,但在useEffect之外未定义窗口。有什么解决办法吗?很有趣<代码>窗口在javascript中是全局的,
    窗口。本地存储
    应该在代码中的任何地方都可用。您可以将整个
    getInitialBannerState
    移动为
    setState
    中的匿名内联函数,即
    setState(()=>{..})
    。您也可以尝试删除
    窗口
    ,直接调用
    本地存储
    。异步内联似乎不起作用。谢谢你的回复anyway@Justin我的回答是否充分解决了您的问题,或者您是否仍有顾虑(或者需要时间测试解决方案)?是的,现在它工作得很好
    const BannerContext = createContext({});
    
    export const BannerProvider = ({ children }) => {
      const [banner, setBanner] = useState(() => {
        const bannerState = window.localStorage.getItem("bannerState");
        return bannerState !== null ? JSON.parse(bannerState) : true;
      });
    
      useEffect(() => {
        window.localStorage.setItem("bannerState", banner);
      }, [banner]);
    
      return (
        <BannerContext.Provider value={{ banner, setBanner }}>
          {children}
        </BannerContext.Provider>
      );
    };
    
    const BannerContext = createContext({});
    
    export const BannerProvider = ({ children }) => {
      const [banner, setBanner] = useState(false);
    
      useEffect(() => {
        const bannerState = window.localStorage.getItem("bannerState");
        setBanner(bannerState !== null ? JSON.parse(bannerState) : true);
      }, []); // <-- no dependency, run once on mount
    
      useEffect(() => {
        window.localStorage.setItem("bannerState", banner);
      }, [banner]);
    
      return (
        <BannerContext.Provider value={{ banner, setBanner }}>
          {children}
        </BannerContext.Provider>
      );
    };