React Js Performance - reactjs

I am using react(V0.13.3),flux(V2.0.3)
I have a component that has many inner components.
While the inner component getting updated, the browser is going off. I am unable to scroll click and some time I get a pop up saying:
unresponsive script would you like stop.
I am following all React life cycle methods and implementing the shouldComponentUpdate method.
I think the DOM Diffing is eating so much CPU time and RAM allocated to the browser.
Any idea about why I have this issue and how I could get out of it?

Reactjs can easily go into endless render cycles. Let's say you put a method that pulls Data from the server in componentDidUpdate and it mutates the reducer that is used by a parent Component. Boom. The component tree rerenders. Your shouldComponentUpdate may be useless bc the input is not the same reference. And the server gets hit again. Endless loop.
The solution is to use guards. When you hit your componentDidUpdate (or wherever you hit the backoffice) method for the first time, the method that mutates the reducer should set a kind of IsLoading variable on the reducer. you check this variable to see if you should fire off your mutating request again. This guards against needless rerenders

Related

In React, is it possible to memoize a list of components and their internal state?

[This is the Codesandbox with all of the code that exemplifies the issue I'm having. Sorry, SO doesn't allow for proper React code with TSX, etc.]
I have some tabs, naturally, whenever I click on each of them, my state changes (namely selectedTab) and the body that's being rendered. Each tab item has a body that goes with it, the first tab, in my case, has a component that, if you click, a count is increased. Well, whenever the tab changes, that count gets reset. In fact, it's a full-rerender all around.
The problem with doing a full re-render is that - not only is it inefficient, given how the user's gonna use it, but it also adds fuel to the fire: what if the user inputs something on a tab, then switches to another tab to do something else and then back to the original one? He's just lost what he typed in.
Naturally, this can be solved if we render all of the tabs' content upfront and we just play with display: none, and it'd be a good solution, but I'm also trying to learn.
I understand how React re-renders things and why this happens, but is there a way to fix it?
In my case, if you look at useTabs, the content variable simply looks at the corresponding tab's component key and takes outputs that. It's there that, I think, I need to memoize things.
Uhm, I guess you can't prevent calling your custom hook, this will lead to invariant violation error.
These hooks in the component will be executed on each render -> thus 'resets' your tabs.
You should rely on useEffect dependencies argument to run conditional code to see if values needs to be changed.
as long as your in the same app you could use contextApi,react context docs otherwise you can use localstorage, localstorage tutorial
or just create this state in the parent component and pass it down as props?

Isn't it ridiculous to check if a component is mounted within the `componentDidMount` life cycle method?

I have for a long while assumed that code I put inside the componentDidMount life cycle method gets called only if the component is mounted. But now I am being told that it might not be the case at all times. For instance, while I am fetching some data inside the componentDidMount method, a user could navigate to another component and cause my component to unmount. And when the data fetching is done, they tell me, the line of code after the data fetching continues naively executing as if the component is still mounted, and that causes some nasty error. Isn't it react's job to ensure that my code doesn't run when my component is unmounted, and resumes only when it is mounted?
UI-programming in general must be asynchronous, such that pressing button doesn't freeze the entire visuals. Therefor flexibility must be left in the framework, like not halting everything just to wait for lifecycle methods. This is the programmers job. API just promises that componentDidMount is called at certain point, nothing else.
If you anticipate long running process in componentDidMount, you could periodically check for instance if componentWillUnmount has been called and if so then cancel execution.

componentDidMount does show intermediate state even though React docs suggest otherwise

1st premise:
componentDidMount() is invoked immediately after a component is mounted (inserted into the tree).
2nd premise:
You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state.
both from https://reactjs.org/docs/react-component.html#componentdidmount
My conclusion:
Based on the above, mounting cannot be the last step in displaying to the browser, otherwise what is rendered and mounted (any intermediate state) before componentDidMount will always be shown.
However, based on my experience, I've found that any state specified in the constructor does in fact get shown before any overriding state changes in componentDidMount.
This is suggesting to me that premise 2 is incorrect. My conclusion is therefore incorrect as well. Mounting must be the final step in displaying to the browser.
Can anyone clear this up for me?
I believe if you set the state in componentDidMount synchronously, the new state will be the only one shown (or at least the switch would happen so fast after rendering it would be impossible to detect).
If you're trying to set it asynchronously, such as using results from a fetch, then you would see the initial state until the async call is completed.

Will componentWillMount run again if component is re-rendered because of parent component?

Will componentWillMount run again if component is re-rendered because of parent component?
No, componentWillMount is called only once.
Also, componentDidMount is called only once.
componentDidUpdate is called on every re-render.
To correctly understand about the react lifecycle methods you can go through this link.
https://engineering.musefind.com/react-lifecycle-methods-how-and-when-to-use-them-2111a1b692b1
The short answer is NO
It's called once right before your component is about to be rendered to the DOM.
The long answer is:
componentWillMount
Your component is going to appear on the screen very shortly. That chunky render function, with all its beautifully off-putting JSX, is about to be called.
Most Common Use Case: App configuration in your root component.
Can call setState: Yes, but don't. Use the default state instead.
componentDidMount
Here is where you load in your data. ComponentDidMount is also where you can do all the fun things you couldn’t do when there was no component to play with. Basically, here you want to do all the setup you couldn’t do without a DOM, and start getting all the data you need. Most Common Use Case: Starting AJAX calls to load in data for your component.
componentWillReceiveProps
Perhaps some data that was loaded in by a parent component’s componentDidMount finally arrived and is being passed down. Before our component does anything with the new props, componentWillReceiveProps is called, with the next props as the argument.
shouldComponentUpdate
shouldComponentUpdate should always return a boolean — an answer to the question, “should I re-render?” Yes, little component, you should. The default is that it always returns true. It's an awesome place to improve performance.
componentWillUpdate
Most Common Use Case: Used instead of componentWillReceiveProps on a component that also has shouldComponentUpdate (but no access to previous props). It’s basically the same as componentWillReceiveProps, except you are not allowed to call this.setState.
componentDidUpdate
Here we can do the same stuff we did in componentDidMount — reset our masonry layout, redraw our canvas, etc. Basically, we use it when it's all said and done, but we don’t want to waste time to redraw the canvas every time it updates. Most Common Use Case: Updating the DOM in response to prop or state changes.
componentWillUnmount
Here you can cancel any outgoing network requests, or remove all event listeners associated with the component. Basically, clean up anything to do that solely involves the component in question — when it’s gone, it should be completely gone.

React state update while rendering

I need to update a state in my react app while rendering the content. Is there any option to update state while rendering.
Note: I am very new to react
You can use componentDidUpdate() Lifecycle method.
and inside componentDidUpdate() function update your state.
FYI: componentDidUpdate() calls every time if component gets updtated.
https://reactjs.org/docs/react-component.html
Futureproofing Note: answer relevant to v16.4.
The answer to your question depends on what you mean by saying "while rendering".
When react invokes the render method of a component, it does not really render anything, yet. The results of the render method will undergo "reconciliation", which means that it will be compared to what's rendered at the moment. If a difference is detected, react will actually re-render the DOM, as effectively as it can.
This means that you can not do anything when react is actually rendering / re-rendering the DOM, since your code is not being executed.
You can, however, do something after the render method has been invoked.
As others have stated before me, the componentDidUpdate method is the place.
Note that the fact that this method has been invoked does not necessarily mean react has re-rendered the DOM. It only assures that the component is in sync with the DOM.
Do note that since setting state CAN cause a re-render, so you should really be careful about setting state in componentDidUpdate - or you might cause an infinite loop of sorts.
Even if you correctly implement shouldComponentUpdate, stopping the render cycle from ever reaching cDU- react docs suggest the result of sCU can be taken as a hint in the future, which will break your app in future releases.
So, if you must setState in cDU - you must check that this setState is required, and is not a side-effect of setting the state in the first place.

Resources