Is it safe to call componentWillReceiveProps() with side effects - reactjs

In React's componentWillReceiveProps function, if I check whether the props have changed first, is it ok to then make an AJAX call? It seems that this function may be called multiple times in React Fiber (post 16 beta) and this blog (https://medium.com/#baphemot/understanding-reactjs-component-life-cycle-823a640b3e8d) suggests that no side effects should be performed. However, I didn't see such a warning in the React docs and I figured that the AJAX call was made only if the props changed that that would be OK.

According to recent (React 16.3+) documentation, this is considered unsafe and in reply to your exact query:
Using this lifecycle method often leads to bugs and inconsistencies,
and for that reason it is going to be deprecated in the future.
If you need to perform a side effect (for example, data fetching or an
animation) in response to a change in props, use componentDidUpdate
lifecycle instead.

It's ok to make a call in OnWillReceiveProps but it's up to you to define a condition that makes sense, if your condition is well made you should not have a lot of call. Anyway you should in most of case avoid the use of OnWillReceiveProps which is kind of greedy in term of perfomance

Related

Get isLoading state of manually initiated RTK Query mutation

I'm working on a Nextjs project with RTK Query. Can someone tell me how to access the isLoading state of the mutation that is initiated like this https://redux-toolkit.js.org/rtk-query/api/created-api/endpoints#initiate. I don't want to use the generated hook useLoginMutation but instead get the data by unwrapping the returned result after dispatching like this await dispatch(api.endpoints.login.initiate()).unwrap() because I don't want my form to re render. Thank you in advance!
because I don't want my form to re render.
Hi, RTK Query author here.
Generally, you can use the selectFromResult option to reduce the amount of fields returned from the hook, and as such also reduce the amount of rerenders (as less things are changing).
Generally though, I have to strongly advise you: don't care about the amount of rerenders on this level. React is made to fastly rerender your components. One, two, or even five rerenders within a 1-3 seconds frame should not make any difference for your application - usually, your component will rerender on every keypress in your form anyways!
If, and only if you are seeing actual performance degradation, you get to the point of optimizing things like this - and then you would see if somewhere you have dozens or hundreds of rerenders, but still do not care about single-digit rerender numbers. If single-digit rerenders are a problem for you, you have heavy computation logic inside your components, and you need to optimize that - the execution of one of your component functions should always be in the sub-milliseconds. Then that's the place to optimize.
As for triggering the mutation with initiate: It will be loading until your await continues and done after that. If you just need that information, there is no need to access an isLoading state. You must set the component state if you need that information in your component. And that would trigger a rerender. You see where I am going: use the hooks! That's what they are made for.
Also, if using initiate: make sure to unsubscribe the result afterward or it will stay in cache forever. Again, this is something the hooks do for you.

React Test Renderer Act Function

I’ve gone through all the documentation I can find. What does the react test renderer act() function actually do? They give short justifications here and there, but I mean at a more technical level.
Ty!
https://reactjs.org/docs/test-renderer.html#testrendereract
This document is the best explanation I've found, although it still seems incomplete.
In short:
In synchronous use (i.e. the callback function you pass to act() does not return a Promise, and you don't await the results), act(f) runs f, then makes sure that any React state updates and effects started during f are finished before returning.
In asynchronous use (f returns a Promise, and then you await the results of act(f)), it... maybe also magically waits for any Promises created during f? It's not really clear. In a GitHub issue filed on the above document, someone asked the author to clarify this, but they haven't responded.

Is using useEffect absolutely necessary?

I've been using React Hooks for a few months and have strictly adhered to using the useEffect hook as per the documentation.
A new colleague has joined the team and he is asking why is useEffect necessary. We've gone through the documentation together but he points out that implementing useEffect causes extra renders.
Here is a simple use case: A button is pressed to fetch some data. The click is handled by a Click event handler. He is wondering why he can't make the async call to the endpoint directly within the event handler.
I'm looking for an explanation that goes beyond "the docs say you shouldn't" and actually explains what the danger or downside of doing this is.
Might anyone be able to share why?
In short it's used for any side effects (not only fetching data):
A side effect is any application state change that is observable outside the called function other than its return value. Side effects include:
Modifying any external variable or object property (e.g., a global
variable, or a variable in the parent function scope chain)
Logging to the console
Writing to the screen
Writing to a file
Writing to the network
Triggering any external process
Calling any other functions with side-effects
Side effects are mostly avoided in functional programming, which makes the effects of a program much easier to understand, and much easier to test.
Haskell and other functional languages frequently isolate and encapsulate side effects from pure functions using monads.

React - Is it poor form to have a lot of logic in render()?

So,I've got a component called a Project, which has a child called ProjectDates.ProjectDates receives its parent's start/end dates, and calculates the percentage completion.
I'm currently doing this calculation in render() so that I don't have to do it both in componentDidUpdate and componentDidMount. Is that correct, or is there a more appropriate lifecycle hook that I should be using?
I think all your suggestions are in general wrong. Lets take them one by one:
1) componentWillMount. You can have some logic here - but it is not recommended to introduce any side dependencies here. So in really world when you usually have to interact with back end - its of little help. Must better choice - componentDidMount where you do not have such restrictions.
2) componentWillUpdate. You should be careful here - to not end up with endless loop. Calling setState here is prohibited as it might in calling componentWillUpdate again and so on. Consider using componentWillReceiveProps.
3) render. This method should not contain any other logic except the one that prepares (renders) the content of the component. Consider moving your "business" logic to componentWillReceiveProps/componentDidMount or maybe constructor if applicable.
I recommend to go through the official docs before making decisions about your architecture.

Multiple Apollo mutations

I followed the Apollo documentation to provide two mutations (createUser then signInUser) on a single React component, but one mutation (the "outer" one - signInUser) is not accessible to my code (this.props.signInUser is not a function). Maybe my server-side-enabled setup is masking one mutation, but I don't see where. Help appreciated :)
See full code here.
EDIT: same issue when using compose, see code.
You just need to name the mutations when passing them into the component, otherwise they are ALL called mutate, and override one another.
(By using the props function)
Here's a full example with named mutations:
https://gist.github.com/Siyfion/a2e9626ed431f8ff91af2c9b8cba1d67
It was caused by my apollo higher-order component which did more complex things than just calling Apollo's graphql (related to server-side rendering) and somehow must be masking properties. I bypassed this SSR behaviour for these mutations (not needed), see code.

Resources