简体   繁体   English

localStorage 在刷新时使用初始 state 值进行更新

[英]localStorage getting updated with initial state value on refresh

I am trying to use localStorage to persist the component's state on refresh.我正在尝试使用 localStorage 在刷新时保留组件的 state。 The component works fine on initial render of the page, but the component fails with the message saying: TypeError: items.map is not a function该组件在页面的初始渲染时工作正常,但组件失败并显示以下消息:TypeError: items.map is not a function

TestLocalStorage
src/TestLocalStorage.jsx:54

Here's the code:这是代码:

import React, { useEffect, useState } from 'react';

function TestLocalStorage() {
    const [items, setItems] = useState([]);

    useEffect(() => {
        const storedData = localStorage.getItem("items");
        if(!storedData) {
            Axios.get('/url').then(response => {
                const serviceResponse = response.data.hits.map(obj=> ({ ...obj, voteCount: 0 
           }));
                localStorage.setItem("items", JSON.stringify(serviceResponse));
                setItems(serviceResponse);
            });
        } else {
            setItems(storedData);
        }
    }, []);

    useEffect(() => {
        localStorage.setItem("items", JSON.stringify(items));
    })

    function increment(id) {
        const elementsIndex = items.findIndex(element => element.objectID === id )
        items[elementsIndex].voteCount++;
        setItems([...items]);
    }

    return (
        <table cellPadding="0" cellSpacing="0" width="100%" background-color="#f6f6ef">
         <tr>
            <td>
               <table border="0" cellPadding="0" cellSpacing="0" width="100%">
                    <tr bgcolor="#ff6600" style={{ color:"white", fontWeight: "bold" }}>
                        <td> Comments </td>
                        <td> Vote Count</td>
                        <td> vote</td>
                    </tr>
                    {
                        items.map((item) => {
                            return (
                            <tr className="table-rows" key={item.objectID}>
                                <td>{ item.comments }</td>
                                <td>{ item.voteCount }</td>
                                <td>
                                    <div 
                                        style={{ 
                                            width: 0, 
                                            height: 0, 
                                            borderTop: 0, 
                                            borderLeft: "5px solid transparent", 
                                            borderRight: "5px solid transparent", 
                                            borderBottom: "10px solid grey" 
                                        }}
                                        onClick={() => increment(item.objectID)} 
                                    />
                                </td>
                                <td>{ item.title }</td>
                            </tr>)
                        })
                    }
               </table>
            </td>
         </tr>
      </table>
    );
}
export default TestLocalStorage;

But I noticed that on second render the localStorage has initial value [] set instead of the newly updated one.但我注意到,在第二次渲染时,localStorage 设置了初始值 [] 而不是新更新的值。 Not sure where I am going wrong.不知道我哪里出错了。 Please help请帮忙

storedData will be string, you need to JSON.parse(storedData) to be able to use that and do map on it storedData将是字符串,您需要JSON.parse(storedData)才能使用它并对其执行map

Do the parsing on the string which you are extracting from local storage by using JSON.parse()使用 JSON.parse() 对从本地存储中提取的字符串进行解析

function TestLocalStorage() {

        const [items, setItems] = useState([]);
    
        useEffect(() => {
            const storedData = localStorage.getItem("items");
            if(!storedData) {
                Axios.get('/url').then(response => {
                    const serviceResponse = response.data.hits.map(obj=> ({ ...obj, voteCount: 0 
               }));
                    localStorage.setItem("items", JSON.stringify(serviceResponse));
                    setItems(serviceResponse);
                });
            } else {
                setItems(storedData);
            }
        }, []);

        ...............
        ...............
        ...............

}

Modify your function like below.如下修改您的 function。 Also, do a check for items value before doing map operation on the array to prevent uncaught exceptions此外,在对阵列执行 map 操作之前检查项目值,以防止未捕获的异常

function TestLocalStorage() {

        const [items, setItems] = useState([]);
    
        useEffect(() => {
            const storedData = JSON.parse(localStorage.getItem("items"));
            if(!storedData) {
                Axios.get('/url').then(response => {
                    const serviceResponse = response.data.hits.map(obj=> ({ ...obj, voteCount: 0 
               }));
                    localStorage.setItem("items", JSON.stringify(serviceResponse));
                    setItems(serviceResponse);
                });
            } else {
                setItems(storedData);
            }
        }, []);

        ...............
        ...............
        ...............
        return (
           .....
           .....
           items && items.map((item) => {
           .....
           .....
        )
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM