Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing getDerivedStateFromProps with useEffect

I'm converting a class component to a function component and wanted to see if useEffect() could replace the following static function

static getDerivedStateFromProps(props) {
    const { path } = props.match;
    if (path === '/login') {
      return { loginStatus: true };
    } else {
      return { loginStatus: false };
    }
  }

Following is the new replacement function. It's doing what it's supposed to be doing, which is to change the state according to the props, but I'm not too familiar with useEffect() and I'm just wondering if I'm not losing anything by converting to this.

const { path } = props.match
useEffect(() => {
    if (path ==='/login'){
        setLoginStatus(true)
    } else {
    setLoginStatus(false)
    }
}, [ path ])
like image 889
Kevvv Avatar asked May 16 '19 17:05

Kevvv


People also ask

How do I replace getDerivedStateFromProps?

You can have a state for the previous path and the current path and only call setLoginStatus when they are different. If you only want to setLoginStatus(true) when path == 'login' then using the useEffect is correct. This part of the code will only run when path changes. And this happens because of [ path ] .

What does getDerivedStateFromProps return?

getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing. This method exists for rare use cases where the state depends on changes in props over time.

Why is getDerivedStateFromProps static?

The reason getDerivedStateFromProps is static is to discourage any side-effects during the render phase. For example, updating or using props on the instance. This isn't safe anymore with the upcoming async rendering. It is called when a component is created and each time it recieves a new props.


1 Answers

You should check the docs

You can have a state for the previous path and the current path and only call setLoginStatus when they are different.

If you only want to setLoginStatus(true) when path == 'login' then using the useEffect is correct.

This part of the code will only run when path changes. And this happens because of [ path ].

useEffect(() => {
    if (path ==='/login'){
        setLoginStatus(true)
    } else {
    setLoginStatus(false)
    }
}, [ path ])

And if you are using some router, probably your effect will run only in the initial render.

I'm just wondering if I'm not losing anything by converting to this.

No, it's fine, that's the way you should do it

Also take a look at You Probably Don't Need Derived State

And here

like image 92
Vencovsky Avatar answered Oct 14 '22 06:10

Vencovsky