React Rendering Pages Twice - javascript

I'm working on a React app at the moment, and I've got the assignment to try-catch runtime errors when they occur. I've implemented the ErrorBoundary solution found on the React website.
Now, this solution works great, but I have a problem. Whenever a page loads, whether this is from navigation or a hard reload, React renders the ErrorBoundary component correctly (because there is an error in a child component), but after a few seconds, renders the child component anyway and then crashes. I have looked all over my code to find the culprit, scoured Google for tangeable errors, but could not find what is causing this behaviour.
This behaviour was already present before the ErrorBoundary solution was implemented. It has been in here since I started working on it a few weeks back.
Also, this behaviour makes it so that when React first renders a page, the this.props is empty. Only after the few seconds have passed, will the this.props be filled. It hasn't been a problem up until now, while we always check the this.props object for our needed data. But I do not want to hack around this behaviour any longer and find a solution.
I've looked at the component lifecycle functions, but I only really use the constructor and the componentDidMount functions to load and set data, and use the setState function to change data along the way in a few components.
I have as drastic as it sounds removed all code from the render of my components, starting from the top, all the way to the logical last child component, to find out which component is the culprit, but it did not make any difference in the behaviour I'm getting.
Below are some screenshots of what happens:
I've started with React, creating the tic-tac-toe example application. But in this tutorial, I did not see behaviour like this.
Any help is welcome!

Related

Will React functional component always re-renders as long as it has a child component?

I have been struggling with a performance problem in a React (React Native to be exact) app for days. It boils down to this problem:
When a Parent function component has another function component as the Child, the Parent will always re-renders whenever its own parent (GrandParent) re-renders. And this is true even if all components are memoized with React.memo.
It seems to be a fundamental problem for React, because in this common situation, HeavyParent will always re-renders whenever LightGrandParent re-renders, even if neither HeavyParent nor LightChild needs re-rendering. This is obviously causing a massive performance problem for our app.
<LightGrandParent>
<HeavyParent>
<LightChild />
</HeavyParent>
</LightGrandParent>
I can't believe this is how React works. Did I miss anything?
I created a sandbox to show what I mean.
A component re-renders if its state changes, or when its parent re-renders. Re-renders on state changes are normal. The other case sometimes is problematic. In this components tree you pasted
<LightGrandParent>
<HeavyParent>
<LightChild />
</HeavyParent>
</LightGrandParent>
LightGrandParent consumes HeavyParent with props.children, which gives you out of the box optimization, as React won't re-renders HeavyParent if LightGrandParent re-renders because of an internal state change.
Now, if you wanna also control re-renders because of LightGrandParent's parent re-rendering, you could use memo to memoize HeavyParent.
But this won't work because HeavyParent consumes LightChild as children, which is a new refrence on each render, and memo comparing new props with previous to do caching.
The answers #yousumar and a few other folks provided were correct. However, this also means a very surprising phenomenon demonstrated as follows:
I know many developers won't see this as a problem and will just say "hey this is how it works". But I personally think that this at least represents a shortcoming in React's fundamentals, as it violates the principle of least surprise. Also React's core doc should have pointed this out so that developers like me wouldn't get burned.

Prevent Vue.js re-rendering child components

I've got a complex component which does all its rendering in a render function. There are multiple parts to this, and different bits of the view get rendered - one of these things is a filter bar, showing the filters that have been applied.
What I'm noticing happening, is if I apply a filter which in turn presents this bar, it causes everything else to be fully re-rendered. This is causing a number of other issues and I need to try and stop it from happening.
I've never come across this issue when using normal templates as Vue seems to handle these very intelligently, but I have no idea how to tackle this. The only thing I can think of is setting a key on each thing I don't want re-rendered but not sure if this will a) solve the problem, and b) be possible for the content that is passed in through a slot
Has anyone else faced this issue, and if so how can it be solved?
I had a similar issue when using vuetify text inputs in a complex component which was causing the app to slow down drastically.
In my search I found this link which was specific to vuetify:
high performance impact when using a lot of v-text-field
then found out that this is actually a vue thing from this GitHub issue:
Component with slot re-renders even if the slot or component data has not changed
and there is plan to improve this in it is tracked here (vue 3 should resolve this issue):
Update slot content without re-rendering rest of component
so after reading through all these I found some workarounds that helped me a lot to boost the performance of my app, I hope these will help you as well:
divide that complex component into smaller ones specially when there is some bit of code that changes data that bounds to template causing re-rendering (put them in their own component)
I moved all data layer control to the vuex store, instead of using v-model every where and passing data as events and props, all the data is updating in the store through an action and read from the store through a getter. (from data I mean somethings that is being looped in the template in a v-for, API results, and so on... all of them is being set, updated and read through the store. my components still have the data object but only for the things related to the style and template control like a boolean to control a modal or an imported icon which is used in the template and alikes)
lastly I wrote a function called lazyCaller which its job is to update the values in the store with a delay (when immediate data update isn't necessary) to avoid rapid updates comping from something like a text input (with out this every key stroke trigger the value update action)

React useState is not immediately updating the state of an array (react-native)

I made this simple example to explain my problem:
Problem Link
In this example, message should be displayed when 5 is added but it is displaying in next event later to the event when 5 is added. I am new to React so i don't really understand hooks and states yet, i see some other examples similar questions but since i'm completely new to react, all that stuff is a kind of overwhelming for me, i just need the solution for this particular problem.
The problem is that useState and some other hooks are async to improve the perfomance. In order to fix the issue, you should use the useEffect hook whick will run as soon as a certain variable value changes

How to detect rerenders in React JS correctly?

Let's say we have a parent component and multiple functional child components. I want to clearly know if the parent re-renders does the child re-renders or not.
After going through a few articles I came to know there are 3 ways we can detect rerenders. (Let me know if there are more ways.)
1. Put a console.log in the child component.
2. Use Chrome paint flashing option in the settings.
3. Use React dev tool
Do all these ways are correct to know if the component really rerenders? Because it doesn't seem to be work correctly with React.memo.
When I am wrapping the Child component with React.memo it does not print console.log, when the parent component rerenders which is correct. But still with chrome and react dev tools highlights the child component as if it rerendered.
CodeSandbox: https://codesandbox.io/s/bold-cloud-iv0rv
(If we add a new car still the static component is highlighted in green, but as per Memo, it should not rerender.)
Now my doubt, Is paint flashing does not work correctly or React.memo having issues?
Reason
If you use React.memo, you need to use it from parent down to all the child till the end.
Since React.PureComponent share the same feature with React.memo, you can find those explanation in the document as below.
Furthermore, React.PureComponent’s shouldComponentUpdate() skips prop updates for the whole component subtree. Make sure all the children components are also “pure”.
Result
By changing parent component Cars to memo
// Before
export default Cars;
// After
export default React.memo(Cars);
You could find the react-dev-tools in chrome will only show the parent component re-rendered this time as well as no child console.log fired, which is correct. (Compare to previous, all the child also got highlighted)
Before
After
Conclusion
Both console.log and react-dev-tools worked well, you may just need to implement in a proper way following your demand.

React.js: Why is there no componentDidRender event?

I have just started using React, and a couple of times I have thought to myself: "Why is there no componentDidRender event?".
Say that I have a component that renders a table to the DOM, and I want to use bootstrap-sortable on this table to allow the user to sort on whatever column he wants. In the case of bootstrap-sortable you need to run $.boostrapSortable() after the table is drawn, in order to initialize the plugin.
As I see it, there are two handlers on a React component that would be logical to consider to use for this purpose:
componentDidMount: This does not work because the DOM does not seem to be updated at this point of the execution.
componentDidUpdate: This could possibly work, but it does not fire on the initial render.
I am not saying that React is actually missing a componentDidRender function, because I assume that there is a perfectly logical explanation as to why it is not there. I am just asking if someone could explain why such a function is not present, and what would be the "React way" to handle a case like the one above.
In componentDidMount you can do: this.getDOMNode() to get a reference to the underlying DOM for that component. So if you do want to use your mounted component with jQuery you can do:
componentDidMount: function() {
$(this.getDOMNode());
}
http://facebook.github.io/react/docs/working-with-the-browser.html
Here's a fiddle which shows jQuery acting on the DOM node of a react component:
http://jsfiddle.net/sa5e88ys/1/
As you can see, it adds a border to the div as expected. If you're still having problems I guess it could be with the plugin you're using rather than jQuery or react?
Although there's no componentDidRender, you can make a method with the desired behavior and call it in both componentDidMount (which is only called after the first render) and componentDidUpdate (which is called after every render but the first).
Also, this is the preferred way of getting a ref to a DOM node from within the component:
https://facebook.github.io/react/docs/refs-and-the-dom.html

Categories