1

I'm working with Nextjs and Next-Router, I have a side bar which indicates where you are in the application. The highlighted key on the sider is set by setting defaultSelectedKey which is a state like so:

    const [selectedMenuItem, setSelectedMenuItem] = useState(...);

It's important this selected key is correct as otherwise it can indicate you're in a different section of the application, specifically on refresh where the current state is lost.

I can get the state either by setting it is '1' and then running a use effect that sets it again like so:

    useEffect((): void => {
        const item = items.find((item) => item.route === router.pathname)
        setSelectedMenuItem(item!.key)
    }, [])

or I can do it directly in the state initiation like so:

    const [selectedMenuItem, setSelectedMenuItem] = useState((items.find((item) => item.route === router.pathname))!.key);

Is there any benefits / drawbacks to either method? What is best practise in this scenario?

max
  • 37
  • 7
  • 1
    Well the benefit of not using the effect is that you will get one less render. Looking at what you have posted, the useEffect is just wasting time / resources. – Keith May 15 '23 at 14:32
  • Good point, something just felt wrong about so much happening when the state is being initialised. – max May 15 '23 at 14:34

1 Answers1

1

You can use either approach, but the drawback with setting the default state through the useEffect is that code inside useEffect will be executed on the first render, but the updated state will be set to selectedMenuItem only on the second render, so there will be some flash of the first state.

The correct approach is to use function as the argument of useState as this code will be executed only on the first render:

const [selectedMenuItem, setSelectedMenuItem] = useState(() => (items.find((item) => item.route === router.pathname))!.key);

Artur Minin
  • 271
  • 1
  • 10
  • Just be aware that `useState` doesn't have a dependency array, so if `router.pathname` can update you would want to avoid the function variant. IOW: make sure this function is pure. – Keith May 15 '23 at 15:01
  • Yeah, I agree with you, in this case `useEffect` comes handy – Artur Minin May 15 '23 at 15:34