I've created a JSfiddle
In this fiddle, initially a list of checkboxes is rendered based on the props which are passed to the component.
On clicking the Re-render button, the same component is rendered with a different set of props.
Now, please follow the below steps-
Load the jsfiddle
Check any of the checkbox (let's say I check the 2nd and 3rd checkbox)
Click Re-render button
Even after rendering the component with new props, the state of checked boxes which you checked remains unchanged (2nd and 3rd are still checked)
Why does it happen?
How can I re-render the component with new set of props such that the state of checkboxes do not persist.
Because React's diff algorithm is smart. The conditions to rerender a new component are:
either the component has a different key (Different Keys)
or it actually is a different HTML element (Different Node Types)
Here's a working example: http://jsfiddle.net/lustoykov/ufLyy3vh/
The thing is - neither condition to rerender your input element is satisfied, so React really reuses the old input. What I've done is to generate a new key for every input element on each rerender. React assumes this is a new element because the key changes and the input gets rerendered with the correct value.
The Math.random() is necessary in order to make sure you generate different keys, it's like: Hey, React, this element has changed - please rerender it.
However, I would argue against this approach with different keys, because it is against React's philosophy. Why would you use React if you rerender the same element every single time? That's the core of React - not to rerender when the component is the same. Instead, you should use onChange handler to update only the values of your inputs without explicitly rerendering the whole input component.
Have a look how to work with React forms.
Related
I have the user select options, these are saved in the state of the parent component. The parent component is the entire web page with the "form".
When the user presses "Submit", I want the child component that uses these options to re-render using these new props passed into it. A default generation is visible when you load the page.
However, I don't want it done before 'Submit' is pressed, only after.
All I can think of is to remove the element from the node and regenerate it but this is not a good way to use React. Let me know if more clarification/context is needed. I am new to React and I am doing this project to familiarize myself with it and it's behaviors.
Thank you!
I suppose what you want is the re-rendering of the child component when the props passed to it(the child component) change. A component re-renders when its state changes, so you can let the child component have its own state, and the state value are initialized(or componentDidMount) by the props. So anytime the props change, state would automatically change and hence the component will re-render after you press the Submit button.
Also if you want the child component to be rendered only after the Submit button has been pressed, you can maintain isVisible in the state and conditionally render it using ternary operator or if__else block
I created a react project using redux as state management. I have two different states stored in the same reducer and used by two different components. But every time I change the state in one component, the other component also re-rendered. How to prevent this rendering behavior?
You can try my sandbox here: https://pjm8e.csb.app/
I put some console.log inside each component, and both are rendered when the button clicked
This is happening, because both of the components are connected to the whole state. So if you update only a small part of the state, it causes them both to rerender. You can use hooks for dispatch and selectors to only connect to relevant parts of the store. Here is a sandbox example:
https://codesandbox.io/s/shy-architecture-1n0g7?file=/src/Consumer2.js
In our experience, thinking about how the UI should look at any given moment, rather than how to change it over time, eliminates a whole class of bugs.
From React Docs
From my understanding, this means that React only updates what's necessary, rather than destroying and re-constructing the entire DOM tree again. Am I wrong?
Can anyone please help me understand the quoted statement?
Thanks.
From my understanding, this means that React only updates what's necessary, rather than destroying and re-constructing the entire DOM tree again. Am I wrong?
If you want to know the short answer, I have to say it is true, React will update the necessary elements in DOM whenever it needed.
But if you want to know how it's done, and when React will update the DOM and its element I have to it is varying to different several things, like project architecture, using proper methods (proper hooks in functional component eg. useCallback, useMemo, and so on) and so on.
When it truly gets rerender then?
As far as I know, there are two ways React finds out when to rerender the DOM.
Passing elements to ReactDOM.render
Update a state
What is ReactDOM.render?
This will call the render() method from react-dom (Where we usually import it as ReactDOM) and it will render a React element into the DOM in the supplied container and return a reference to the component (or returns null for stateless components). Also if the React element was previously rendered into the container, this will perform an update on it and only mutate the DOM as necessary to reflect the latest React element.
What does state mean?
The state object is where you store property values that belong to the component. So when you got a component and that component has their own specific variables where changing them should affect the DOM you should use it, then whenever state gets changes the component will be updated.
So what I even talk about project architecture and this stuff, when I didn't mention anything about it above?
Let's say we got a project with one parent component and 3 child component just like this:
Component 1
- |- Component 2
- - |- Component 3
- - - |- Component 4
So whenever you a state in Component 4 all of the DOM elements will be get rerendered, why then? Because Component 4 is a child of Component 3 and so on, so when the child state gets change it will force the parent to rerender then the whole DOM will rerender once per state change.
Final Note
So, at last, we should be always considered a good architecture and hierarchy for our project or when it necessarily use built-in methods like useMemo to avoid such a thing.
lHello everyone, here is the problem.
We have a grid component with some filtering enabled. When the filtering is applied, if a certain callback-prop exists, it is called with the filtered data as an argument.
The problem is this. If said datagrid is wrapped by a parent component and the parent component saves the filtered data in it's state, it causes the parent to rerender, but also the datagrid. However, when the datagrid renders it runs it's filtering logic, which causes the callback(which is setState() call) to run.
So, to avoid the loop I introduced a variable to the parent component class and save the data there, but it doesn't seem so good to me.
Another option would be redux, just add a new action and dispatch it when the filtering runs.
Any other ideas?
Since you're also asking for other ideas, may I suggest React hooks. They allow finer-grained control, such as multiple states, reducers, memoized callbacks, effects that are only called when inputs change, etc.
A select element within a React.js component takes 2 clicks to update in Firefox, but updates correctly on first click in Chrome and Safari.
It's a component using Redux + React-Redux and the value of the select element is dictated by a store value passed to it via mapStateToProps.
React Devtools shows the value of the select element updating correctly but the DOM itself doesn't update on the first click.
Redux Devtools is showing the correct actions being passed and correct state changes being made.
I've created a isolated recreation of the component tree in CodeSandbox (it functions correctly here so not a lot of help): https://codesandbox.io/s/jl7rpw3635
Here's a gif of the problem
Thanks in advance!
I ended up solving this issue by modifying the select component to render its options on mount, then attach them to a class property, avoiding re-rendering each option again every time the select component updates (they never change so it probably makes sense to do this) - https://codesandbox.io/s/m7m2qqp9py