【问题标题】:What's the best way to set localStorage in React?在 React 中设置 localStorage 的最佳方式是什么?
【发布时间】:2022-12-12 13:23:23
【问题描述】:

我正在构建一个游戏,我想将用户的输赢存储在浏览器的本地存储中。我有一个看起来像这样的简单组件:

import { useState, useEffect } from 'react';

const Game = () => {
    const [wins, setWins] = useState(0);
    const [losses, setLosses] = useState(0);


    // Report wins to localStorage
    useEffect(() => {
        localStorage.setItem('wins', wins);
    }, [wins]);

    // Report losses to localStorage
    useEffect(() => {
        localStorage.setItem('losses', losses);
    }, [losses]);

    // Get any existing data in localStorage
    useEffect(() => {
        const winCount = localStorage.getItem('wins');
        const lossCount = localStorage.getItem('losses');

        winCount ? setWins(winCount) : setWins(0);
        lossCount ? setLosses(lossCount) : setLosses(0);
    }, []);


    return (
        <div className="game">
            Wins: {wins} | Losses: {losses}

            <-- Game Stuff Here -->
            <-- Wins & Losses Get Incremented During Game -->
        </div>
    )
}

问题是在渲染时,前两个useEffect 运行并用零重置 localStorage。我知道有一个解决方法使用 useRef 来阻止 useEffect 在第一次渲染时运行,但感觉有点花哨。这是唯一的解决方案还是在渲染时不覆盖 localStorage 有更好的做法?

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    我什至会说你不需要在每次重新呈现组件时都获取 localStorage。

    
    // Get any existing data in localStorage
    
    const winCount = () => Number(localStorage.getItem('wins')) || 0;
    const lossCount = () => Number(localStorage.getItem('losses')) || 0;
    
    
    const Game = () => {
        const [wins, setWins] = useState(winCount());
        const [losses, setLosses] = useState(lossCount());
    
    
        // Report wins to localStorage
        useEffect(() => {
            localStorage.setItem('wins', wins);
        }, [wins]);
    
        // Report losses to localStorage
        useEffect(() => {
            localStorage.setItem('losses', losses);
        }, [losses]);
    
        return (
            <div className="game">
                Wins: {wins} | Losses: {losses}
    
                <-- Game Stuff Here -->
                <-- Wins & Losses Get Incremented During Game -->
            </div>
        )
    }
    

    【讨论】:

    • 这也很好用!我发布了一个非常相似的解决方案,它去掉了从 localStorage 获取数据的 useEffect,而是将逻辑放在初始状态设置器中。
    【解决方案2】:

    解决了!

    无需获取 useEffect 中的 localStorage 值。我们可以在设置状态值时简单地获取它们。

    我的组件现在看起来像这样:

    import { useState, useEffect } from 'react';
    
    const Game = () => {
        const [wins, setWins] = useState(() => {
            const storageWins = localStorage.getItem('wins');
            return storageWins ? parseInt(storageWins) : 0;
        );
        const [losses, setLosses] = useState(() => {
            const storageLosses = localStorage.getItem('losses');
            return storageLosses ? parseInt(storageLosses) : 0;
        );
    
    
        // Report wins to localStorage
        useEffect(() => {
            localStorage.setItem('wins', wins);
        }, [wins]);
    
        // Report losses to localStorage
        useEffect(() => {
            localStorage.setItem('losses', losses);
        }, [losses]);
    
    
        return (
            <div className="game">
                Wins: {wins} | Losses: {losses}
    
                <-- Game Stuff Here -->
                <-- Wins & Losses Get Incremented During Game -->
            </div>
        )
    }
    

    【讨论】:

      【解决方案3】:

      最好的办法设置本地存储和易用性

      export const localData = {
          set(key, value) {
              localStorage.setItem(key, JSON.stringify(value));
          },
          get(key) {
              const stored = localStorage.getItem(key);
              return stored == null ? undefined : JSON.parse(stored);
          },
          remove(key, value) {
              localStorage.removeItem(key);
          }
      };
      
      localData.set("user_name", "serialCoder")
      
      console.log( "After set ?", localData.get("user_name") )
      
      localData.remove("user_name")
      
      console.log( "After remove ?", localData.get("user_name") )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-27
        • 1970-01-01
        • 1970-01-01
        • 2021-12-08
        • 2015-11-23
        • 2012-06-04
        • 1970-01-01
        相关资源
        最近更新 更多