简体   繁体   中英

Persist data with localStorage - React.js

I'm confused about how to use localStorage to persist the data that's coming from calling the API. I want whenever I refresh the page, the callApi inside useEffect to not render new data and keep the existing data unchanged.

Any help would be appreciated.

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { Layout, Loading, OverviewHeader, OverviewSubHeader, SiteCard } from '../components';

const Overview = () => {
    const [loading, setLoading] = useState(true);
    const [sites, setSites] = useState([]);

    useEffect(() => {
        async function callApi() {
            const response = await axios.get(`https://randomuser.me/api/?results=3`);
            const sites = response?.data?.results;
            console.log('sites', sites);
            setSites(sites);

            await localStorage.setItem('sites', JSON.stringify(sites));
            setLoading(false);
        }
        callApi();
    }, []); 

    return (
        <div>
            <Layout>
                <OverviewHeader />
                <OverviewSubHeader />
                <div className='overview-page-wrapper'>
                    {loading ? (
                        <Loading />
                    ) : (
                        sites.map(site => {
                            return (
                                <React.Fragment>
                                    <SiteCard
                                        key={site.login.uuid}
                                        siteId={site.login.uuid}
                                        image={site.picture.large}
                                        firstName={site.name.first}
                                        lastName={site.name.last}
                                        city={site.location.city}
                                        country={site.location.country}
                                        sensors={site.dob.age}
                                        notifications={site.registered.age}
                                        latitude={site.location.coordinates.latitude}
                                        longitude={site.location.coordinates.longitude}
                                        {...site}
                                    />
                                </React.Fragment>
                            );
                        })
                    )}
                </div>
            </Layout>
        </div>
    );
};

export default Overview;

I'm not too sure what you're trying to accomplish, seeing as you'd likely want to refresh that data at some point. Maybe you could indicate what behaviour/scenario you're trying to cater for?

In any case, to answer your question, what you could do is smth like:

const [displayedSites, setDisplayedSites] = useState([])

// this does both setting the state for your UI 
// and stores to localStorage
const setAndSaveDisplayedSites = (fetchedSites) => {
  setDisplayedSites(sites)
  localStorage.setItem('sites', JSON.stringify(sites))
}

useEffect(() => {
  (async function () {
    const localSites = localStorage.getItem(sites);
    if (!localSites) {
      // this will only ever fetch if it is your first time mounting this component
      // I suppose you would need to call setAndSaveDisplayedSites
      // from a "refresh" button
      const fetchedSites = await getSitesFromAPI()
      setAndSaveDisplayedSites(fetchedSites)
      return
    }
    const parsedLocalSites = JSON.parse(localSites)
    setDisplayedSites(parsedLocalSites)
  })()
}, [])

also checkout this hook that takes care of some things for you: https://usehooks.com/useLocalStorage/

Use the useContext hook for this purpose OR if you really just want to use the local storage anyhow, then use it but manage different states/variables for that.

  1. Your current state (that you want to render on the screen)
  2. Your fetched data (the one that you want to keep)

Hope this makes sense. Thankyou!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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