2

I have a component provided by an external library which I need to provide an access token to. This access token is saved in localStorage at this point and I would like to read it and pass it to the component. This is my attempt using useEffect but this fails with the error {code: "initialization-error", error: "Access token required"}

const test: NextPage = () => {
  const router = useRouter()
  let accessToken = ''
  useEffect(() => {
    const at = localStorage.getItem('accessToken')
    console.log(at) // prints out the correct access token
    if (at !== null) {
      accessToken = at
    }
  }, [])

  return (
      <WebSdk
        accessToken={accessToken}
        expirationHandler={() => Promise.resolve(accessToken)}
        onError={(error) => {
          console.log(error)
        }}
      />
  )
}

export default test

I'm guessing the useEffect hook runs after the component renderes - how can I read from local storage before or as the component renders?

1 Answer 1

2

Since you are using nextjs you can't call the localStorage directly, so you have to check if the bowser has "initialized", something like this:

const test: NextPage = () => {
  const router = useRouter()
  const [initialized, setInitialized] = useState(false);
  const [accessToken, setAccessToken] = useState('');

  useEffect(() => {
    const at = localStorage.getItem('accessToken') || '';
    
    setInitialized(true);
    setAccessToken(at);
  }, [])
 
  if (!initialized) {
    return null;
  }  

  return (
      <WebSdk
        accessToken={accessToken}
        expirationHandler={() => Promise.resolve(accessToken)}
        onError={(error) => {
          console.log(error)
        }}
      />
  )
}

export default test

I'm guessing the useEffect hook runs after the component renderes

Yes the component will render first before the hooks can be triggered, this is the equivalent of "componentDidMount" (if the hook's second parameter is empty) in early verions of react.

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

4 Comments

I get Type 'Promise<string | null>' is not assignable to type 'Promise<string>'. for the expiration handler - tbh. I don't really understand what that expirationHandler is for so not sure what the best way to fix this is.
@sev oh you're in typescript, I have updated my answer. because localstorage tends to return a null if it doesnt exist, so just make sure to fallback to empty string if null/undefined
If I try this as you have now it fails and I think its because that part of the code is being executed on the server ( I ran with if (typeof window === 'undefined') { console.log('You are on the server'}) How can I make this run on the browser in nextjs?
@sev I have updated my answer, can you try that one?

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.