2

I have a React Context API in use in my NextJS web app.
I'd like to persist a value throughout the web app. I know I can use the Consumer tag inside the Provider tag to update the value.

Like so:

<ProfileContext.Provider>
    <ProfileContext.Consumer>{... some logic ...}</ProfileContext.Consumer>
</ProfileContext.Provider>

But I'd like to use the useContext() call to update a value by passing in a State object.

user_profile.js

import { useState } from 'react'
import { createContext, useContext } from 'react'

const ProfileContext = createContext()

export function ProfileProvider({ children }) {
  const [profile, setProfile] = useState("default value")

  return (
    <ProfileContext.Provider value={{ profile, setProfile }}>
      {children}
    </ProfileContext.Provider>
  )
}

export const useProfileContext = () => {
  return useContext(ProfileContext)
}

The issue is the value I assign using setProfile(...) does not retain value when I navigate to another page.

user_account.js

...
export default function UserAccount() {
  const profileContext = useProfileContext()

  profileContext.setProfile("SOME TEXT PROFILE VALUE")
  console.log("PROFILE CONTEXT: ", profileContext.profile)  // This will show previously set value 

  return (...)
}

_app.js

export default function App(pageProps) {
  return (
    <ProfileProvider>
      <Component {...pageProps} />
    </ProfileProvider>
  )
}

When I navigate to some other page, the state will not have changed and will return null or the default value.

some_other_page.js

...
export default function Home() {
  const profileContext = useProfileContext()
  console.log(profileContext.profile)  // "default value" 

  return (...)
}

My main guide was https://www.netlify.com/blog/2020/12/01/using-react-context-for-state-management-in-next.js

Most other examples I've read use the Provier-Consumer tags to access and change the Context value.

1
  • Could you provide a working example on live editor like codesandbox. Commented Jul 7, 2022 at 18:44

3 Answers 3

0
+50

If you want to persist the value through page navigation or refreshes, you'll likely need to store the profile value in something that's persisted and load the value from the data store to the context. You can use something like a db or possibly local storage. On app load, you'll make the API call to retrieve these values and store it in your context.

Sign up to request clarification or add additional context in comments.

Comments

0

You should wrap profileContext.setProfile call into useEffect

  useEffect(() => {
    profileContext.setProfile("SOME TEXT PROFILE VALUE")
  }, [profileContext]);

Cannot update a component while rendering a different component warning

Comments

0

First of all: Your implementation looks fine.

The key part is when you said:

When I navigate to some other page, the state will not have changed and will return null or the default value.

Since you are using useContext(), which is a client-side-hook, server-side navigation will not automatically persist the state of client components.

Simple Solution

Do not rely on server side navigation (e.g. a-tags,@Next/Link-tags, window.href...).

Use router.push() with the useRouter hook to achieve client-side navigation instead.

If you need to rely on server-side navigation...

... persist the data needed in localStorage and useEffect to retrieve upon component mount.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.