简体   繁体   中英

How can I wait for the value from localStorage?

I am trying to get values that i save in localStorage but the components render faster and the values are stored later. So for the first time it comes undefined. How can I wait for the values to be stored and than render?

HERE I GET THE VALUE AFTER IS STORED

The first time comes null because needs time to be stored.

function getUsername() {
    const userData = store.get('user');
    const userFullName = userData && JSON.stringify(userData.fullName)
        ? JSON.stringify(userData.fullName).replace(/"([^"]+(?="))"/g, '$1')
        : null
    console.log(userFullName);
    return userFullName;
};

HERE I RENDER

<AccountFound fullName={getUsername()}/>

I don't know if you have worked with hooks, but you could try to do the request for the getUserName inside a useEffect and, once the request has finished, store the value inside a useState variable. Then you render the component based on that.

Also, you can try to store in a cost the value of full name and then do:

const fullName = getFullName()
fullName ? <Accountfound fullName={fullName} /> : "Loading data..."

Usually, you would want to get the values from localStorage or cookies as soon as your app boots up and then handle retrieved data as initialState for your app state.

I suppose every state management lib has its own way to update components and to perform actions with side effects like localStorage.setItem .

If you're not using any lib, you could implement basic observer pattern :

function makeObservable(target) {
  let listeners = [];
  let value = target;

  function get() {
    return value;
  }

  function set(newValue) {
    if (value === newValue) return;
    value = newValue;
    listeners.forEach((l) => l(val));
  }

  function subscribe(listenerFunc) {
    listeners.push(listenerFunc);
    return () => unsubscribe(listenerFunc);
  }

  function unsubscribe(listenerFunc) {
    listeners = listeners.filter((l) => l !== listenerFunc);
  }

  return {
    get,
    set,
    subscribe,
  };
}

Then combine it with useState hook by performing subscribe on mount:

const cachedUser = localStorageOrCookies.get("user");
const userObservable = makeObservable(JSON.parse(cachedUser));

export default function useUser() {
  const [user, setUser] = Reaact.useState(userObservable.get());

  React.useEffect(() => {
    return userObservable.subscribe(setUser);
  }, []);

  function set(newUser) {
    userObservable.set(newUser);
    localStorageOrCookies.set("user", JSON.stringify(newUser));
  }

  const actions = {
    setName: name => set({ ...user, name }),
    setAge: age => set({ ...user, age }),
  };

  return [user, actions];
}

And now you can use it in your components:

import useUser from "./path/to/useUser";

const SomeComponent = () => {
  const [user, userActions] = useUser();

  return <>
    <AccountFound fullName={user.name}/>
    <button onClick={() => userActions.setName("Vasya")}>Change name</button>
  </>;
}

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