Should useEffect be used to get derived state from props - reactjs

I read How to sync props to state using React hooks : setState() that is basically about how to mimic getDerivedStateFromProps in a functional component. The accepted answer said to use useEffect. But the problem is that this would cause an extra unnecessary render, as some comments pointed out. So I wanted to ask a separate question about specifically whether useEffect should be used in this case.

Related

UseEffect: why is fetching data considered a side-effect but not accessing window.location?

I always thought of a side-effect as a read or write operation that is performed while rendering a functional component, and that accesses resources outside of those provided as props. Sort of like the definition of a pure function.
So when I needed to read window.location, I figured it had to be in a useEffect. Turns out the linter doesn't require that window.location be a dependency, so I guess it's ok to access window directly. This means my mental model of a React side-effect is wrong... But why?
If merely fetching data (which is a read operation) is considered a side-effect, then why isn't window.location?
So now I'm wondering, are functional components actually not really pure? Are they only "write pure" but not "read pure"?
How the useEffect or any other memoizing hooks(useCallback, useMemo,...) work works is:
Component re-renders
The dependency list is looked through to detect changes in any of them
If a change is detected, the function inside the useEffect is called
The issue with window.location or any other outer scope variables is that they do not initiate a component re-render to begin with.
This is the exact message on ESLint
Outer scope values like 'window.location.href' aren't valid
dependencies because mutating them doesn't re-render the component
And to answer your question, yes and no.
According this article :
A React component is considered pure if it renders the same output for
the same state and props
So if you add a dependency to an outer scope variable like window in your component, you can't call that component pure anymore.

Is useEffect inside custom hook considered a bad practice?

I was trying to create a reusable hook which includes 2 other mutation hook from react query which does 2 different operations. I was successfully able to create my custom hook and everything is working as expected. My only question is, while building the hook I had to use a useEffect inside my custom hook. I am just wondering if it is a bad practice to have a useEffect inside a custom hook and do I need to change my approach? Will there be any performance issue because of this? Is there something I should be aware of?
It's a very common thing to do. The official documentation describes a custom hook that uses useEffect.
The only thing you should be aware of is that, as always, your hook isn't supposed to intentionally break hook isolation by maintaining an arbitrary shared state outside the hook itself.
I think the "intentionally breaking hook isolation by maintaining an arbitrary shared state outside the hook itself" refers to what happened to me. I was storing a "variable" in the custom hook (with useState) but I was wanting that variable to be accessible in the outside React component, but sometimes the custom hook state was reset, so that value was also reset, and the React component would have suffered from this.
I think the general idea is to always maintain order, you define state in the outer hook/React component, pass that state into custom hooks, the custom hook can generate other data that can be returned as after some processing steps (like with useEffect) and the data can be used in the outer hook/React component as a "state generated by some initial state" which is persisted ONLY in the outer hook/React component caller.
So, in your case and mine, NEVER initialize & maintain an outer hook/React component caller state in the custom hook or NEVER modify the initial state given by the outer caller, in your custom hook.
Sorry, it might be confussing what I wrote, but this is still not very clear for me too. Hope it is clearer though than the short answer Igor gave you.
Good luck !

The order of react hooks

I am trying to understand how React hooks work reading official docs:
https://reactjs.org/docs/hooks-rules.html
And there they say that react relies on the order hooks are called. I still don't get why the order is of importance and why a hook placed in a conditional will cause bugs, could anyone explain?
Particularly this sentence makes me confused:
React wouldn’t know what to return for the second useState Hook call
why?? Does react somehow binds useState with useEffect?
Then, this question:
So how does React know which state corresponds to which useState call?
From my understanding there is only one state, so why they are talking about states (plural)?

What is the use case of useMemo in React?

I need help to understand when to use useMemo hook in React vs useState + useEffect. From what I've understood after reading other questions on S.O. and websites :
With useState you can create a value (changeable through the setter) and you can use useEffect to do whatever you need if some of the dependencies listed in the dependency array changes. On first render for example your component will be rendered with the initial value passed to useState, then the effect will run and your component will re-render with the new value you set with the setter in your effect.
With useMemo you can create a value that will be computed from a function you give to the hook and it will change if some of the dependencies in the dependency array changes. So far, to me, it looks like useState + useEffect except you don't have the setter to change the value. On render your useMemo will run if one of the dependencies has changed. Difference here : your component will wait for the value to be computed before rendering (not sure about this part).
From what I've read, useMemo should be used for heavy operations. But if it's blocks the rendering of the component what's the point ?
Some says that with the dependency array you can avoid unnecessary updates but I can also do it with useEffect without blocking the render ? If I don't have a heavy component to render, isn't it faster to use useEffect ?
Thank you :)
Edit :
I accepted Philip Feldmann's answer as it fits my needs. As suggested in the comments you can take a look at this question for a global comparison :)
You are correct, useEffect runs after rendering as a side effect. That means that when you don't want to block the render loop, you can use your version.
That version will however trigger another rerender through calling the setter.
The initial time to paint might be faster, but you'll instantly block the render loop again by setting the new value, which in most cases should be slower than just using useMemo directly.

Why is an anti-pattern letting a react component to edit its own props?

I was searching for an answer to another problem and I found this answer (link) I'm just curious why is it that modifying its own props is an anti-pattern, and why isn't it that modifying its own state is not and anti-pattern?
In react, props is an object of data that is unlikely to change in the lifecycle of the component, and state is data that is likely to change in the lifecycle of the component.
It helps create explicit rules for where developers should put things that do/do-not change.
React update pages very quickly by knowing exactly that data changes will either come strictly from a parent(as props) or come internally as state.
the exact function checks loosely if state/props are the same, then https://github.com/facebook/react/blob/master/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js#L881-L883
I'd recommend reading about how react "reconciles" data for changes and making updates to the dom.
https://facebook.github.io/react/docs/reconciliation.html

Resources