ethdude12
ethdude12

Reputation: 23

Next.js + React Context. Not getting past default values?

I have a context that looks like this:

const peopleContextDefaultValue = {
  name: null,
  age: null,
  setName: null,
  setAge: null,
};
    ...

  const [name, setNameState] = useState();
  const [age, setAgeState] = useState();

  const setName = (payload) => {
    setNameState(payload);
  };

  const setAge = (payload) => {
    setAgeState(payload);
  };

  const value = {
    name,
    age,
    setName,
    setAge,
  };

  return (
    <>
      <PeopleContext.Provider value={value}>
        {children}
      </PeopleContext.Provider>
    </>
  );

And I'd like to set some default values off my .env, after the app loads for the first time. So I put this useEffect in _app.js:

function MyApp({ Component, pageProps }: AppProps) {
  const { setName, setAge } =
    usePeople();

  useEffect(() => {
    const effect = async () => {
      const name = process.env.NEXT_PUBLIC_NAME;
      const age = process.env.NEXT_PUBLIC_AGE;

      if (name) {
        setName(name)
      );
    

      if (age) {
        setAge(age)
      }
     };

    effect();
  }, []);

  return (
    <PeopleProvider>
      <Navbar />
      <Component {...pageProps} />
    </PeopleProvider>
  );
}

export default MyApp;

But, I keep getting this error:

setName is not a function

The problem seems to be that setName is staying with its default value from peopleContextDefaultValue, but I don't understand why. Does anyone understand this? Any idea how to fix/approach this?

Thanks a ton in advance for any help!!

Upvotes: 2

Views: 1491

Answers (1)

Enfield Li
Enfield Li

Reputation: 2530

Provider should be at the highest level of any components using its context, you are accessing context state, so you need to wrap <MyApp /> in it as well:

// For a normal React app, but won't work for Nextjs
<PeopleProvider>
  <MyApp />
</PeopleProvider>

In case of Nextjs, the highest level component is the _app.js file, so above won't work, since there aren't any higher level component than _app.js.

So I'd recommend move your current logic from _app.js file to index.js file, while keeping the provider code, and your existing code should work, otherwise, you can take a look at this answer.

Upvotes: 1

Related Questions