dai-shi / react-hooks-global-state

[NOT MAINTAINED] Simple global state for React with Hooks API without Context API

Home Page:https://www.npmjs.com/package/react-hooks-global-state

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

getGlobalState should not be used in render

Slessi opened this issue · comments

Hi, receiving the following in a situation I don't think I can do anything about

getGlobalState should not be used in render.

My App.js:

const App = () => (
  <GlobalStateProvider>
    <ApolloProvider client={ApolloClient}>
      <Layout />
    </ApolloProvider>
  </GlobalStateProvider>
);

Here I pass ApolloClient as a prop for the react-apollo context. I import this client from a separate file. Part of creating the client includes creating an object with a callback which in my use case, needs access to a global state item.

new ApolloClient({
  link: ApolloLink((operation, forward) => {
    operation.setContext({ magic: getGlobalState('magic') });
  }),
});

The use of getGlobalState here is triggering the error however there is no rendering going on in this file, at least none that I have control over. It isn't feasible to do something like

const App = () => {
    const magicState = useGlobalState('magic');

    return (
      <GlobalStateProvider>
        <ApolloProvider client={createClient(magicState)}>
          <Layout />
        </ApolloProvider>
      </GlobalStateProvider>
    );
}

The above will create issues with how react-apollo works (there is cache and the like stored in the client, so i need to stick to one instance).

Is it necessary to throw this error?

Hm, interesting. The fact that you are using getGlobalState and react-apollo invokes setContext in render means the value is not reactive but it reads the value passively.

I'm not sure how your code works entirely, but if it doesn't require the reactivity, it wouldn't be good to use the global state. How about defining the variable externally?

let magic;
export const getMagic = () => magic;
export const setMagic = (m) => { magic = m; };

import { getMagic } from ...;
new ApolloClient({
  link: ApolloLink((operation, forward) => {
    operation.setContext({ magic: getMagic() });
  }),
});

If this doesn't work, there must be some use cases that I don't yet understand.
I would like to come up with solutions in such cases, preferably without removing the warning.

The warning exists because often people can misuse getGlobalState where it should be useGlobalState.

BTW, one of my motivations to develop this library is to use it with react-apollo. I'd use it for global state that apollo-link-state doesn't fit well with.

@dai-shi I store information about the currently authenticated user and set headers for API requests in the link. I use the reactivity inside the app to change view information but I also need the value in the link to authenticate with API

The external things you suggest to create are already catered by the library, I'm just thrown an error when I try to use them

@Slessi Your use case seems totally making sense. On a second thought, I can't think of any other solutions than removing the warning. Let me work on it in a minute.

Thanks for your library :)