beekai-oss / little-state-machine

📠 React custom hook for persist state management
https://lrz5wloklm.csb.app/
MIT License
1.47k stars 53 forks source link

Dynamically set store name with data from backend #146

Closed cosminv6u closed 1 year ago

cosminv6u commented 1 year ago

Hello,

I want to load different stores from localStorage depending on the logged in user. So I wanted to call createStore a little bit later, in an useEffect, after I get from backend the username, so that I can set the name of the store containing the username. This way depending on which user is logged in, the correct store is retrieved.

I pasted an example of what I need and I wasn't able to make it work. I was able to create new stores with the correct names and have them populated with the state I wanted, but if I do a Refresh in Browser, the created stores are then ignored and data is not retrieved from them, but from some kind of an empty store.

Is this supported? Have I done something wrong? Should I do it differently? I felt like this way was the least invasive way of doing it, otherwise if I add 'username' as a root inside the state object, I will have to do more refactor of our code.

`

export default function App() {
  const { username, isLoading } = useUsername();
  const [storeCreated, setStoreCreated] = React.useState<boolean>(false);

  React.useEffect(() => {
    if (!isLoading && username) {
      console.log('createStore CALLED');
      createStore({
        yourDetails: {
          firstname: "bill",
          lastname: "luo"
        },
        {
          name: `myName_${username}`,
          middleWares: [],
          storageType: localStorage,
        }
      });
      setStoreCreated(true);
    }
  }, [username, isLoading]);

  return (
    <StateMachineProvider>
      <div className="App">
        <h1>Little State Machine</h1>
        <Form />
      </div>
    </StateMachineProvider>
  );
}

`

cosminv6u commented 1 year ago

I was able to solve it like this, so this can be closed.

`

function StateMachineProviderWrapper({ children }: { children: React.ReactNode }): JSX.Element {

  const { username, isLoading } = useUsername();
  const [storeCreated, setStoreCreated] = React.useState<boolean>(false);

  React.useEffect(() => {
    if (!isLoading && username) {
      console.log('createStore CALLED');
      createStore({
        yourDetails: {
          firstname: "bill",
          lastname: "luo"
        },
        {
          name: `myName_${username}`,
          middleWares: [],
          storageType: localStorage,
        }
      });
      setStoreCreated(true);
    }
  }, [username, isLoading]);
  if (storeCreated) {
    return <StateMachineProvider>{children}</StateMachineProvider>
  }
  return <>{children}</>
}

export default function App() {
  return (
    <StateMachineProviderWrapper>
      <div className="App">
        <h1>Little State Machine</h1>
        <Form />
      </div>
    </StateMachineProviderWrapper>
  );
}

`