Javascript React挂钩和localStorage未设置正确的值
您好,我有一个想法,制作一个钩子来增加字体大小并在localStorage中保存首选项 基本上,我有一个从1到4的状态,然后当我点击add按钮时,我将+1添加到状态中,直到我达到数字4 在移除按钮上,我从状态中移除1,直到1 但我对如何将其保存到我的位置存有疑问 基本上,如果我不将useState与getInitialValue一起使用,它将正常工作 与此gif类似,如果我手动添加值,它会起作用: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
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
范围内,包括两端。