【问题标题】:Store number using localStorage with custom hook React使用带有自定义钩子 React 的 localStorage 存储编号
【发布时间】:2022-01-10 16:57:28
【问题描述】:

我正在尝试为计数器存储一个数字,该计数器初始化为 0,每次用户上传照片时计数为 1。我在配置文件 console.log orderHook.orderCount 中未定义。在 localStorage 我得到 {count:0} 的 console.log
非常感谢任何帮助!

LocalStorage.js:

import { useState, useEffect } from 'react';

function getStorageValue(key, defaultValue) {
    // getting stored value
    const saved = localStorage.getItem(key);
    const initial = JSON.parse(saved); // unexpected character @ line 1 column 1 
    // const initial = JSON.stringify(saved); 
    return initial || defaultValue;
}

export const useLocalStorage = (key, defaultValue) => {
    const [value, setValue] = useState(() => {
        console.log(key)
        return getStorageValue(key, defaultValue);
    });

    useEffect(() => {
        localStorage.setItem(key, JSON.stringify(value));
    }, [key, value]);

    return [value, setValue];
};

Count.js:自定义钩子

import { useLocalStorage } from "../../Utilities/localStorage/localStorage"; // Local storage hook

function useOrderCountHook() {
    const [orderCount, setOrderCount] = useLocalStorage({count: 0}); // The profile image

    const changeOrderCount = () => {
        setOrderCount({ count: orderCount.count + 1 })
    }
    return { orderCount, changeOrderCount };
    // return [orderCount, changeOrderCount];
}

export default useOrderCountHook;

Profile.js:使用自定义钩子

    const orderHook = useOrderCountHook(); // How the photo count hook is called

    console.log(typeof (orderHook.orderCount)) // undefined
    console.log(orderHook.orderCount) // undefined

    const handleUploadChange = e => { // Input onChange 
        if (e.target.files[0]) {
            setImage(e.target.files[0]);
        } else { }
        return handleCountChange()
    };

    const handleCountChange = () => { // Function for custom count hook
        if (orderHook.orderCount === undefined) {
            return 
        } else {
            return orderHook.orderCount
        }
    }
      return (
                        {
                            currentUser ?
                                <input
                                    type="file"
                                    for="Upload Image"
                                    accept="image/*"
                                    name="image"
                                    id="file"
                                    onChange={handleUploadChange}
                                    onClick={handleUploadChange}
                                    style={{ display: "none" }}
                                />
                                : ''
                           }

                        <i className="bi bi-camera">      
                            {orderHook.orderCount === undefined ?
                                <span className="banner-list-font mx-1">0 photos</span>
                                :
                                <span className="banner-list-font mx-1">{orderHook.orderCount.count} photos</span>
                            }
                        </i>

**更新**
所以我设法让它工作,但是当我退出用户并重新登录时,如果我尝试上传照片,我会收到错误无法读取未定义的属性(读取“计数”)。这是 defaultValue 道具,并且该控制台记录为未定义。我认为问题在于计数被存储为对象?

localStorage.js:

import { useState, useEffect } from 'react';

// function getStorageValue(key, defaultValue) {
//     const saved = localStorage.getItem(key);
//     console.log(saved, defaultValue, key)// => null undefined {count:0}
//     const initial = JSON.parse(saved);
//     console.log(initial)
//     // const initial = JSON.stringify(saved); 
//     // return key || defaultValue;
//     return initial || defaultValue;
// }

function getStorageValue(key, defaultValue) {
    const saved = localStorage.getItem(key);
    console.log(saved, defaultValue, key)// => null undefined {count:0}
    if (saved === null) {
        return defaultValue;
    }
    return JSON.parse(saved);
}

export const useLocalStorage = (key, defaultValue) => {
    console.log(key, defaultValue)// => {count:0} undefined
    const [value, setValue] = useState(() => {
        return getStorageValue(key, defaultValue);
    });

    useEffect(() => {
        localStorage.setItem(key, JSON.stringify(value));
    }, [key, value]);

    return [value, setValue];
};

Profile.js:
return (
<input
      type="file"
      for="Upload Image"
      accept="image/*"
      name="image"
      id="file"
      onChange={e => { orderHook.changeOrderCount(e); handleUploadChange(e) }}
      onClick={handleUploadChange}
      style={{ display: "none" }}
     />

 <i className="bi bi-camera"></i>                              
    {orderHook.orderCount === undefined || orderHook.orderCount === null ?
     <span className="banner-list-font mx-1">0 photos</span> 
     :
     <span className="banner-list-font mx-1">{orderHook.orderCount.count} photos</span>
     }

【问题讨论】:

    标签: javascript reactjs react-hooks local-storage


    【解决方案1】:

    看起来错误来自您的getStorageValue 函数,这是一个固定的实现:

    function getStorageValue(key, defaultValue) {
      const saved = localStorage.getItem(key);
      if (saved === null) {
        return defaultValue;
      }
      return JSON.parse(saved);
    }
    
    

    我建议使用库而不是编写自己的 useLocalStorage 实现。 查看react-tidy 库中的useStorage 挂钩。

    免责声明我是该库的作者。

    【讨论】:

    • 当我 console.log typeof 和 orderHook.orderCount.count 时,它仍然以字符串形式返回,并且在 Profile 中未定义 :(。老实说,我可能对此深入了解并关闭我不真的很想学习一个新库并尝试从头开始重做和实现所有内容
    • 修复getStorageValue后是否尝试清除localStorage?我认为它读取旧的存储值(即'undefined')。
    • 是的,我试过了,我不明白为什么在 getStorageValue func 键控制台日志为 {count:0} 但将控制台日志保存为 null
    • 在 localStorage devTools 中,它显示 Key 为 [object Object] Value undefined。为什么每次刷新或重新导航回个人资料页面时都会出现 crossOrigin 错误
    • 你能把你的代码放在codesandbox.io或者我可以调试的地方吗?
    【解决方案2】:

    代替:

        const [orderCount, setOrderCount] = useLocalStorage({count: 0}); // The profile image
    

    你应该使用:

        const [orderCount, setOrderCount] = useLocalStorage("count", 0); // The profile image
    

    【讨论】:

    • 我看到了其中的逻辑,但它不起作用
    【解决方案3】:

    大部分更改都在 localStorage.js 中,首先我从 Count.js 获取密钥并将其保存到保存的 var 中,该 var 将当前计数输出为 '{"count":5}'。接下来我创建一个 var currentVal(以前命名为 initial)和 JSON.parse 传入的保存的 var。 JSON.parse 将字符串对象转换回常规的 javascript 对象。现在产生 {count: 5} 的值(或任何当前 count: 是)。然后,如果具有计数 {count: 5} (currentVal) 的预期对象返回 undefined 或 null,则给出将是 {count: 0} 的键,否则返回 currentVal。在这种情况下,键充当默认值,不知道为什么。也不确定这个 localStorage Hook 的可重用性如何,但它应该适用于类似于 Count.js 的任何格式。

    还要注意新的输入 onChange 处理程序和新的条件渲染它下面的跨度。

    LocalStorage.js:

    import { useState, useEffect } from 'react';
    
    function getStorageValue(key, defaultValue) {
        const saved = localStorage.getItem(key);
        console.log(saved, defaultValue, key)
        const initial = JSON.parse(saved); // unexpected character @ line 1 column 1 
        console.log(initial)
        if (initial === null || initial === undefined) {
            return key
        } else {
            return initial
        }
    }
    
    export const useLocalStorage = (key, defaultValue) => {
        console.log(key, defaultValue)
        const [value, setValue] = useState(() => {
            return getStorageValue(key, defaultValue);
        });
    
        useEffect(() => {
            localStorage.setItem(key, JSON.stringify(value));
        }, [key, value]);
    
        return [value, setValue];
    };
    

    Count.js:

    import { useLocalStorage } from "../../Utilities/localStorage/localStorage"; // Local storage hook
    
    function useOrderCountHook() {
        const [orderCount, setOrderCount] = useLocalStorage({count: 0}); // The profile image
    
        const changeOrderCount = () => {
            setOrderCount({ count: orderCount.count + 1 })
        }
        
        return { orderCount, changeOrderCount };
    }
    
    export default useOrderCountHook;
    

    Profile.js:

    const orderHook = useOrderCountHook(); // Photo count hook
                    {
                        currentUser ?
                            <input
                                type="file"
                                for="Upload Image"
                                accept="image/*"
                                name="image"
                                id="file"
                                onChange={e => { orderHook.changeOrderCount(e); handleUploadChange(e) }}
                                onClick={handleUploadChange}
                                style={{ display: "none" }}
                            />
                            : ''
                    }
    
                     <div className="">
                        <i className="bi bi-camera"></i>                              
                        {orderHook.orderCount === undefined || orderHook.orderCount === null ?
                        <span className="banner-list-font mx-1">0 photos</span> 
                         :
                         <span className="banner-list-font mx-1">{orderHook.orderCount.count} photos</span>                    
                      </div>
    

    【讨论】:

      猜你喜欢
      • 2020-08-27
      • 2020-12-05
      • 2022-01-24
      • 1970-01-01
      • 2020-08-13
      • 2021-01-20
      • 2021-10-04
      • 2021-12-30
      • 2020-05-22
      相关资源
      最近更新 更多