首页 > 解决方案 > Next.js update state depending on router.asPath

问题描述

I have a next.js multistep form with a Stepper. Stepper has following state on the initial load:

  const [steps, setStepsData] = useState([
    { name: 'Vertrag', status: 'current' },
    { name: 'Dateneingabe', status: 'upcoming' },
    { name: 'Bestätigung', status: 'upcoming' },
  ]);

This state is handeled in context, where I also useRouter to set my URL depending on form step. Every time user clicks next button the following functions is called:

  const nextFormStep = (contract='') => {
    const nextStep = formStep + 1;
    router.push(`?step=${nextStep}`);
    setFormValues({ contract });
  };

So far so good. Now in my context I wish to check if router.asPath === '/?step=1' then it should do smth like this:

router.asPath === '/?step=1' ? setStepsData( steps => [
  { name: 'Vertrag', status: 'current' },
  { name: 'Dateneingabe', status: 'current' },
  { name: 'Bestätigung', status: 'upcoming' },]) : console.log('doesnt work')
}, [])

So, if I just leave it like that I get an error: Too many re-renders. React limits the number of renders to prevent an infinite loop. I figured, I might need to useEffect like this:

useEffect(() => { 
      router.asPath === '/?step=1' ? setStepsData( steps => [
      { name: 'Vertrag', status: 'current' },
      { name: 'Dateneingabe', status: 'current' },
      { name: 'Bestätigung', status: 'upcoming' },]) : console.log('doesnt work') 
}, [])

With that approach state changes only after I hit the reload button in the browser, not on changing to the next form step. How do I reach following behavior: I hit the button next step - the url path changes, state changes, I hit back button, again, the url changes and so does the steps state?

标签: reactjsnext.jsnext-router

解决方案


I simply needed to 'subscribe' to changes of the router as follows:

router.asPath === '/?step=1' ? setStepsData( steps => [
  { name: 'Vertrag', status: 'current' },
  { name: 'Dateneingabe', status: 'current' },
  { name: 'Bestätigung', status: 'upcoming' },]) : console.log('doesnt work')
}, [router])

Got a hint from the comment above and this SO-post: useEffect doesn't update state on route change


推荐阅读