使用带有自定义挂钩 React 的 localStorage 存储编号

Store number using localStorage with custom hook React

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

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: 使用 customhook

    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>

**更新**
所以我设法让它工作但是当我注销用户并现在重新登录时如果我尝试上传照片我得到错误无法读取未定义的属性(读取'count')。这是 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>
     }

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

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

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

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

而不是:

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

你应该使用:

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

大部分更改在 localStorage.js 中,首先我从 Count.js 获取密钥并将其保存到 var saved 中,输出当前计数为 '{"count":5} '.接下来我创建一个 var currentVal(以前称为 initial)和 JSON.parse 传入的保存变量。 JSON.parse 将字符串对象转换回常规 javascript 对象。导致现在的值为 {count: 5} (或任何当前计数:是)。然后,如果具有计数 {count: 5} (currentVal) 的预期对象是 returning undefined 或 null,则给出将是 {count: 0} 的键,否则 return currentVal。在此实例中,Key 充当默认值,不确定原因。也不确定这个 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>