I have a parent class component that has a function in componentWillMount that loops through a list of strings and creates an element for each one and finally setState on this.state.map. Each child element receives a prop which is a state in parent called this.state[element].
The reason I put these elements into this.state.map was because I can change things in (some) upper components without having to re-render the array each time (which is painfully slow) and I didn't want to use shouldComponentUpdate. Plus in the future I can just quickly change elements by toggling different map states.
The problem is, when the parent this.state[element] (that's passed to child as props in the initial componentWillMount) changes, it doesn't update the props for the child. Parent state does change though.
Is this a legit way to do this?
I'm sorry I didn't provide code sample. It's just such a mess at the moment.
Only ReactDOM.render (and serverside rendering etc.), setState, or forceUpdate, will cause your children to re-render. If you are just mutating the state object, React is unaware of this, and will not re-render. Anyways, mutating the state not through setState is not valid, and you should try to keep your state as immutable as possible. In order for you to see the changes in your children, you need to use setState to update this.state[element].
From the React docs:
Notes:
NEVER mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.
Related
I am new to React and a bit struggling with state in React and how and where we need to use it. So far, I found out that "If modifying a piece of data does not visually change the component, that data shouldn’t go into state". So, state is all about re-rendering the UI(I hope I am correct). So, the question I want to ask is Is it true that we use state only for re-rendering the UI only?, nothing else and nothing more?
You can use state in your class components. State is like private data of your component that may change by action made by user.
State is immutable. This means you can not change state directly in following way this.state.someVal = "smth". The only way to change state is using this.setState() method.
When you change state value React automatically re-renders your component without refreshing the page. In other words React.js reacts to your changes
State is an object that is directly tied to rendering the component. The reason why you can't change State directly with say this.state.foo='bar' is that React would have no way of knowing that it needed to re-render the component if you did that. Thus there is a setState method to change the state, which under the hood calls the render function of your component.
Therefore, if you have some data that has nothing to do with rendering the component, you don't want to put it into state, as setting its value will cause unnecessary renders to occur. If you're using class components, you can just put that data on the class directly: this.foo='bar'.
Basically yes! Two examples might be: A - holding a list of items (shopping list, or todo items) that are rendered directly to the UI, that are subject to change as the user adds and removes items. B - a value that determines whether or not you want something to show up on your UI, for example, you might have a state value called 'showNavbar' that is either true or false, depending on whether you want the user to see a navigation bar.
I hope that helps make sense of it in a basic way :)
We use the state for rendering the UI.
Also, I think the State allows React components to change their output over time in response to user actions, network responses, and anything else, without violating this rule.
For this, We use the 'setState' method.
setState() is the only legitimate way to update state after the initial state setup
Lately I've been working on a React app.
In one of the pages which was suffering from slow load, I discovered there was some updates to state, and those variables where not meant to be shown to end user, and they were there to be checked later when some event was raised.
Since those were arrays, I mutating the state directly and event without "setState"ing it (I know mutating the variable is not recommended at all!).
Later when the Event was raised, state variable had correct data and since redundant "setState"s where removed, the page had a significant speed boost and the problem was solved.
Anyone has any similar experiences with "setState" in react?
What do you think about this?
...I discovered there was some updates to state, and those variables where not meant to be shown to end user...
Then they shouldn't be part of state, they should just be properties on the instance (in a class-based component, which I assume you're using; variables you close over in a functional component). state should only contain things that, when changed, cause a re-render. For that reason, you should only change them via setState, so the render is triggered. You're getting away with breaking the rule because what you're changing isn't related to rendering.
Never mutate the state object (or any objects it refers to) directly. But you can mutate non-state properties (or things you close over), that's fine.
If you need those variables to be stored in actual state but them does not have to trigger a render you probably need to implement shouldComponentUpdate lyfecycle callback:
shouldComponentUpdate(nextProps, nextState) {
return nextState.myPropertyThatTriggersRender != this.state.myPropertyThatTriggersRender;
}
Doing that, if all your state's properties that trigger render are checked, other state properties won't trigger a render. But will be still available in state object.
In order to improve performances, you can implement the same check on the child elements (if they are components) that are going to be rendered.
shouldComponentUpdate(nextProps, nextState) {
return nextProps.myPropThatTriggersRender != this.props.myPropThatTriggersRender;
}
From React's DOC:
Use shouldComponentUpdate() to let React know if a component’s output
is not affected by the current change in state or props. The default
behavior is to re-render on every state change, and in the vast
majority of cases you should rely on the default behavior.
When will a React component using hooks re-render?
Let's assume the component:
Manages state with useState
Receives props from its parent
Will a re-render happen directly after the following events, and only at those points in time?
Component receives new props
state is updated
Related Question
Let's assume the component has several useState expressions and a user interaction causes multiple states to update.
Will the component re-render multiple times, once per state value that changed, or will it batch these related changes into one single re-render?
A component will re-render in the following cases considering it doesn't implement shouldComponentUpdate for class component, or is using React.memo for function
Component receives new props
state is updated
Context value is updated(if the component listenes to context change using useContext)
Parent component re-renders due to any of the above reasons
Let's assume the component has several useState expressions and a user
interaction causes multiple states to update.
Will the component re-render multiple times, once per state value that
changed, or will it batch these related changes into one single
re-render?
useState doesn't merge the updated values with previous ones but performs batching like setState and hence if multiple state updates are done together, one render take place.
Found this nice article on this topic. I'll add the summary in case someone needs a quick read.
What causes a render in react?
State modification
Component re-renders when its state is manipulated, simple as that. So, when you modify the state of your component it tends to re-renders with the new state value.
Passing Props
If the parent component has triggered a rerender all the child component will rerender too, generally you would only want the specific child components to rerender only if the component is consuming some props or the passed props are modified but that isn’t the case, it does not matter if the props are consumed, modified or not, the child components will re-render if the parent component has triggered a render.
Using the Context API
When modifying the state which is also the value passed to the context, the whole child components tree would get rerendered. Again doesn’t matter if the child component is consuming the context data or not, it will still rerender. The rerenders depend on the value passed to the provider but still, all the whole components tree would get rerendered.
Passing down references
In case of an object, array and, function comparison is based on references i.e. the exact memory location so, their comparison even though they seem equal yields false, in React Object.is method is used to compare the different values.
Example:
{}==={} //false
[]===[] //false
{a: 5}==={a: 5} //false
[1,2,3]===[1,2,3] //false
(when comparing the previous state to the new state, it returns false because they do not have the same reference. Only the value is the same)
I want to know, what are events, that cause React component to re-render.
I couldn't find full list anywhere, it'd be great if someone writes the list of events, that cause React component to re-render.
I always find the following reference website helpful.
http://reactcheatsheet.com/
Filter by lifecycle events, and you can see the places where setState will trigger a rerender.
__
Update: you now have to filter by "misc"
React component is re-rendered when setState() is called or when props change. You can also force re-render with forceUpdate()
https://reactjs.org/docs/react-component.html#forceupdate
By default, when your component's state or props change, your
component will re-render. However, if these change implicitly (eg:
data deep within an object changes without changing the object itself)
or if your render() method depends on some other data, you can tell
React that it needs to re-run render() by calling forceUpdate().
I know that it is possible to re-render only one component (instead of whole DOM) using shouldComponentUpdate(), but is it possible to only re-render one PROP of one component? In one instance in my app I do not want the entire component to update, but only a specific prop that is being changed.
You probably can't do that because that's not how it's supposed to work. The component is updated in order to reflect all changes made to its state and props. The best way to get around this would be to just not update the props being passed by the parent component.
Alternatively, you could also use the state to hold the values you don't want to be updated, and set these values in the constructor of the component.