Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.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 React挂钩和localStorage未设置正确的值_Javascript_Reactjs_React Hooks - Fatal编程技术网

Javascript React挂钩和localStorage未设置正确的值

Javascript React挂钩和localStorage未设置正确的值,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,您好,我有一个想法,制作一个钩子来增加字体大小并在localStorage中保存首选项 基本上,我有一个从1到4的状态,然后当我点击add按钮时,我将+1添加到状态中,直到我达到数字4 在移除按钮上,我从状态中移除1,直到1 但我对如何将其保存到我的位置存有疑问 基本上,如果我不将useState与getInitialValue一起使用,它将正常工作 与此gif类似,如果我手动添加值,它会起作用: export default function App() { const { fontSiz

您好,我有一个想法,制作一个钩子来增加字体大小并在localStorage中保存首选项 基本上,我有一个从1到4的状态,然后当我点击add按钮时,我将+1添加到状态中,直到我达到数字4 在移除按钮上,我从状态中移除1,直到1

但我对如何将其保存到我的位置存有疑问 基本上,如果我不将useState与getInitialValue一起使用,它将正常工作

与此gif类似,如果我手动添加值,它会起作用:

export default function App() {
  const { fontSize, setSize } = useFontSize();
  console.log(fontSize);
  return (
    <div className="App">
      <button
        onClick={() => {
          setSize(fontSize + 1);
        }}
      >
        add
      </button>
      <button
        onClick={() => {
          setSize(fontSize + 1);
        }}
      >
        remove
      </button>
    </div>
  );
}
export default function useFontSize(defaultSize = { size: 1 }) {
  const [fontSize, _setSize] = useState(getInitialSize);
  function getInitialSize() {
    const savedSize = localStorage.getItem('_size_acessibility_font');
    const parsedSize = JSON.parse(savedSize);
    if (parsedSize) {
      const { size } = parsedSize;
      if (size >= 1 && size <= 4) {
        return size;
      }
    } else {
      return defaultSize.size;
    }
  }

  useEffect(() => {
    console.log(fontSize, 'on useEffect to set on localStorage');
    localStorage.setItem(
      '_size_acessibility_font',
      JSON.stringify({ size: fontSize }),
    );
  }, [fontSize]);

  return {
    fontSize,
    setSize: ({ setSize, ...size }) => {
      console.log(size, 'on function set size');
      if (size > 4) {
        return _setSize(4);
      }
      if (size < 1) {
        return _setSize(1);
      }
      return _setSize(size);
    },
  };
}

但是如果我尝试使用setFont,我会遇到问题(因为它保存在本地存储中):

export default function App() {
  const { fontSize, setSize } = useFontSize();
  console.log(fontSize);
  return (
    <div className="App">
      <button
        onClick={() => {
          setSize(fontSize + 1);
        }}
      >
        add
      </button>
      <button
        onClick={() => {
          setSize(fontSize + 1);
        }}
      >
        remove
      </button>
    </div>
  );
}
export default function useFontSize(defaultSize = { size: 1 }) {
  const [fontSize, _setSize] = useState(getInitialSize);
  function getInitialSize() {
    const savedSize = localStorage.getItem('_size_acessibility_font');
    const parsedSize = JSON.parse(savedSize);
    if (parsedSize) {
      const { size } = parsedSize;
      if (size >= 1 && size <= 4) {
        return size;
      }
    } else {
      return defaultSize.size;
    }
  }

  useEffect(() => {
    console.log(fontSize, 'on useEffect to set on localStorage');
    localStorage.setItem(
      '_size_acessibility_font',
      JSON.stringify({ size: fontSize }),
    );
  }, [fontSize]);

  return {
    fontSize,
    setSize: ({ setSize, ...size }) => {
      console.log(size, 'on function set size');
      if (size > 4) {
        return _setSize(4);
      }
      if (size < 1) {
        return _setSize(1);
      }
      return _setSize(size);
    },
  };
}

我在localStorage上得到了这个信息:

export default function App() {
  const { fontSize, setSize } = useFontSize();
  console.log(fontSize);
  return (
    <div className="App">
      <button
        onClick={() => {
          setSize(fontSize + 1);
        }}
      >
        add
      </button>
      <button
        onClick={() => {
          setSize(fontSize + 1);
        }}
      >
        remove
      </button>
    </div>
  );
}
export default function useFontSize(defaultSize = { size: 1 }) {
  const [fontSize, _setSize] = useState(getInitialSize);
  function getInitialSize() {
    const savedSize = localStorage.getItem('_size_acessibility_font');
    const parsedSize = JSON.parse(savedSize);
    if (parsedSize) {
      const { size } = parsedSize;
      if (size >= 1 && size <= 4) {
        return size;
      }
    } else {
      return defaultSize.size;
    }
  }

  useEffect(() => {
    console.log(fontSize, 'on useEffect to set on localStorage');
    localStorage.setItem(
      '_size_acessibility_font',
      JSON.stringify({ size: fontSize }),
    );
  }, [fontSize]);

  return {
    fontSize,
    setSize: ({ setSize, ...size }) => {
      console.log(size, 'on function set size');
      if (size > 4) {
        return _setSize(4);
      }
      if (size < 1) {
        return _setSize(1);
      }
      return _setSize(size);
    },
  };
}

代码:

export default function App() {
  const { fontSize, setSize } = useFontSize();
  console.log(fontSize);
  return (
    <div className="App">
      <button
        onClick={() => {
          setSize(fontSize + 1);
        }}
      >
        add
      </button>
      <button
        onClick={() => {
          setSize(fontSize + 1);
        }}
      >
        remove
      </button>
    </div>
  );
}
export default function useFontSize(defaultSize = { size: 1 }) {
  const [fontSize, _setSize] = useState(getInitialSize);
  function getInitialSize() {
    const savedSize = localStorage.getItem('_size_acessibility_font');
    const parsedSize = JSON.parse(savedSize);
    if (parsedSize) {
      const { size } = parsedSize;
      if (size >= 1 && size <= 4) {
        return size;
      }
    } else {
      return defaultSize.size;
    }
  }

  useEffect(() => {
    console.log(fontSize, 'on useEffect to set on localStorage');
    localStorage.setItem(
      '_size_acessibility_font',
      JSON.stringify({ size: fontSize }),
    );
  }, [fontSize]);

  return {
    fontSize,
    setSize: ({ setSize, ...size }) => {
      console.log(size, 'on function set size');
      if (size > 4) {
        return _setSize(4);
      }
      if (size < 1) {
        return _setSize(1);
      }
      return _setSize(size);
    },
  };
}
导出默认函数App(){
常量{fontSize,setSize}=useFontSize();
控制台日志(fontSize);
返回(
{
设置大小(fontSize+1);
}}
>
添加
{
设置大小(fontSize+1);
}}
>
去除
);
}
挂钩:

export default function App() {
  const { fontSize, setSize } = useFontSize();
  console.log(fontSize);
  return (
    <div className="App">
      <button
        onClick={() => {
          setSize(fontSize + 1);
        }}
      >
        add
      </button>
      <button
        onClick={() => {
          setSize(fontSize + 1);
        }}
      >
        remove
      </button>
    </div>
  );
}
export default function useFontSize(defaultSize = { size: 1 }) {
  const [fontSize, _setSize] = useState(getInitialSize);
  function getInitialSize() {
    const savedSize = localStorage.getItem('_size_acessibility_font');
    const parsedSize = JSON.parse(savedSize);
    if (parsedSize) {
      const { size } = parsedSize;
      if (size >= 1 && size <= 4) {
        return size;
      }
    } else {
      return defaultSize.size;
    }
  }

  useEffect(() => {
    console.log(fontSize, 'on useEffect to set on localStorage');
    localStorage.setItem(
      '_size_acessibility_font',
      JSON.stringify({ size: fontSize }),
    );
  }, [fontSize]);

  return {
    fontSize,
    setSize: ({ setSize, ...size }) => {
      console.log(size, 'on function set size');
      if (size > 4) {
        return _setSize(4);
      }
      if (size < 1) {
        return _setSize(1);
      }
      return _setSize(size);
    },
  };
}
导出默认函数useFontSize(defaultSize={size:1}){
const[fontSize,_setSize]=useState(getInitialSize);
函数getInitialSize(){
const savedSize=localStorage.getItem(“大小\可访问性\字体”);
const parsedSize=JSON.parse(savedSize);
if(parsedSize){
const{size}=parsedSize;
如果(大小>=1&&size{
log(fontSize,'on useffect to set on localStorage');
localStorage.setItem(
“\u大小\u可访问性\u字体”,
stringify({size:fontSize}),
);
},[fontSize]);
返回{
字体大小,
setSize:({setSize,…size})=>{
log(大小,'函数集大小');
如果(尺寸>4){
返回设置大小(4);
}
如果(尺寸<1){
返回设置大小(1);
}
返回设置大小(大小);
},
};
}
例如:


如果有人能帮助我,我不知道这是否是此上下文的最佳逻辑。

useFontSize
中,您返回

返回{
字体大小,
setSize:({setSize,…size})=>{
log(大小,'函数集大小');
如果(尺寸>4){
返回设置大小(4);
}
如果(尺寸<1){
返回设置大小(1);
}
返回设置大小(大小);
},
};
但是,在
App
中,当它需要一个对象时,只需一个数字
setSize(fontSize+1);
即可调用
setSize

如果更改
useFontSize
以返回

返回{
字体大小,
设置大小:(大小)=>{
log(大小,'函数集大小');
如果(尺寸>4){
返回设置大小(4);
}
如果(尺寸<1){
返回设置大小(1);
}
返回设置大小(大小);
},
};
它应该会起作用

注意,您需要清除当前本地存储,或添加一些错误检查


还要注意的是,虽然这只是一个示例,但添加和删除都使用
fontSize+1

这似乎有点过度设计,并打乱了一些钩子习惯用法。例如,为钩子返回命名对象对不如数组对典型。函数本身很复杂,并且返回
\u setize的结果调用。如果使用
setFontSize
匹配
setSize
,命名会更清晰

({setSize,…size})
有问题,因为调用者(正确地)提供了一个整数

以下是修复这些问题的最低完整版本(由于堆栈片段是沙盒的,所以本地存储是模拟的):


const localStorageMock=(()=>{
常量存储={};
返回{
getItem:k=>storage[k],
setItem:(k,v)=>{storage[k]=v.toString();}
};
})();
const{useState,useffect}=React;
const useFontSize=(defaultSize=1)=>{
常数钳位=(n,lo=1,hi=4)=>Math.min(hi,Math.max(n,lo));
const clean=n=>isNaN(n)?默认大小:夹具(+n);
const storageName=“\u size\u accessibility\u font”;
const fromStorage=clean(localStorageMock.getItem(storageName));
const[fontSize,setFontSize]=useState(fromStorage);
useffect(()=>{
setItem(storageName,fontSize);
},[fontSize]);
返回[fontSize,size=>setFontSize(clean(size))];
};
常量应用=()=>{
常量[fontSize,setFontSize]=使用fontSize();
返回(
字体大小:{fontSize}
setFontSize(fontSize+1)}>
+
setFontSize(fontSize-1)}>
-
);
};
render(,document.body);

很抱歉,我有点困惑,您是否建议不要使用localStorage?不,绝对要使用
localStorage
。我不能在堆栈代码段上使用它,因为它是沙盒,所以对于您的实际代码,您可以将
localStorageMock
更改为
localStorage
,并删除mock函数。我发现您的代码非常繁荣和清晰,最后我的代码有点迷路了,如果我有困难,我会尝试转移到本地存储。我可以在这里发表评论吗?当然可以。退房并离开。作者甚至将localStorage挂接起来,这对于本例来说似乎有些过分。它是通用的:。它所做的只是将数字限制在指定的
lo..hi
范围内,包括两端。