React check how many times a component re-renders - reactjs

I'm working on something and a piece of my code is a bit slow, what I think happens is that the component re-render too many times for no reason.
Is there any way to check how many times a component re-renders in react(or react-native for the matter)?
What i've tried to do is put a console.log after the render method and count how many there are but i'm not sure if that would work.
Thanks in advance!

you can place console.count('counter') in your render function to check this. Here you'll find all the details about console.count link

console.log will work, if you place it within your render function. If you're concerned about a component re-rendering too many times, try extending React.PureComponent. Info about PureComponent can be found in React's docs. You could also look into the shouldComponentUpdate method to see if that will help solve your re-rendering. Info about that is also in their docs. Good luck!

Better than putting console.log in every component is to use this small util
https://github.com/maicki/why-did-you-update
You will be warned in console every time component re-rendered needlessly (e.g. props nor state did change)
Even though it's not maintained anymore it works perfectly.
Best regards

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?

How to debug a React application when component is rendered multiple times?

I am new to React. I noticed that when components in my application render, line simple two dropdowns, even, in this case, breakpoint hits 15-16 times because of the re-rendering. I need to know where should I place my breakpoint or what should I log to console.log each time, so that I'll come to know why the component is rendered, like can I log a particular attribute or state variable?
Yeah, debugging React apps using breakpoints can be a pain because of all the under the hood React work you may have to step through. Yes, console.log can be super useful, and you should check out React Devtools as well.
Put console.log as the first line of the render function starting with a few of the highest level components. They probably don't rerender much.
Work your way down the tree until you find the culprit.
Many times the effect is multiplicative. One component rerenders 5 times and one of it's children rerenders 3 times per parent render will mean 15 rerenders for everything south of that child.

Warning about calling setState on an unmounted component

The warning:
Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the _class component.
Any idea where it can come from. Gotchas or things like that ?
I already looked at all the setState in my code and replaced them to make sure. Can't find where it comes from...
My observations so far:
Only happens in my tests
No problem in the browser
I thought I had more... but with more testing I got all confuse because it didn't fit the patterns I thought I understood...
So ! I understand what the error is but this time the warning is about a _class component so I'm lost... I just upgraded to react-router v4 and it needed a lot of changes so it's hard to localize the source of the warning.
Anyone had had a similar problem before ?
EDIT:
I found the setState that were causing problem. It was in react-router-server. I'll look into it to see if I can fix it !
Thanks #zerkms for the idea to look with a debugger to get the line number since there was no trace in the terminal.
I used the v8 experimental inspector(https://stackoverflow.com/a/39901169/3687661). Works pretty good :)
This is common due to async activities like API calls. For example, this happen when you try to set a state after you receive the data from the server and the corresponding page to receive that state is not mounted.
To avoid this, check if the component is mounted before setting state in that component. Use a flag to check, say this.mounted = true in componentDidMount and change the flag to false in componentWillUnmount. Use this.mounted across the component to check if the component is mounted. This will fix the warning.
Hope this helps!
This usually happens when you call this.setState within a setTimeout or setInterval or some other deferred function.
If you are using setTimeout/setInterval make sure you call clearTimeout/clearInterval in componentWillUnmount.

React lifecycle method when component is fully rendered

I need to do some size calculations when a component is fully rendered. The componentDidMount method, however fires as soon as the component is rendered, but it's children are not. This code for example:
componentDidMount(){
console.log(findDOMNode(this).childNodes.length);
}
outputs 0
What is the proper way to trigger some code once a component has been fully rendered, together with any descendant components.
Edit: I don't want to use componentDidUpdate since that method fires on any update. I just need this to be run once.
Edit2: As #NaisheelVerdhan points out, the docs say that componentDidMount ins invoked on children first, but in this case I'm confused as to why my above example returns 0
Typically you want to perform calculations in the render method itself. Is there some reason you cannot do that?
I am sorry everyone.
The component I was rendering initially mounted empty and was filled later. #NaisheelVerdhan was entirely correct.

forceUpdate VS forceReload

I'm wondering what is the difference between forceUpdate() and forceReload() in ReactJS.
Tried to find some documentation about that but couldn't find some on forceReload()-
Thanks in advance!
Not sure where you saw it, but forceReload isn't a part of React. You presumably couldn't find documentation because there isn't any -- if I search for "forceReload" react right now, this question comes up first.
If you want to make a component rerender without changing its state or props, you should call forceUpdate.

Resources