I was going through a code and found that
this.props.formVisibility = false
As one cannot update the properties in react's component, the code shouldnt have work but the execution went without any errors.
Now I am wondering, On what conditions one is able to edit props in the component?
Suppose you have parent - child relationship. where parent's state pass as props to child component then whenever you want to update props you need to update parents state not props in child component. once state get updated this will update to props as well in child component hope so it clear the point
refer : https://gist.github.com/sebkouba/a5ac75153ef8d8827b98
Related
I am running some tests with react to find out a way for a parent to send an "event" to a child component. In the test application, the parent (CounterController) has a button. When the button is clicked, the parent shall send a reset "event" to the child (Counter) to reset the current count. Like below.
I am new to react, and can not find a way to dispatch/receive events or messages between components. I had a thought to mark the "reset" request as a "state" in the parent, then pass it to the child through props. Then the child clear the "reset" state, through a callback function, to avoid repeating "reset" requests. However, I got the code run into an infinite loop. Here are my codes.
The parent component - CounterController
The child component - Counter
the error logs
I do not feel that I am using react the right way, by asking the child to do something from the parent. Anyway, any idea about how to implement this app in react? How should the data flow be built correctly? Thanks!
You can move up the counter state on the parent ‘CounterController’
and then you pass the counter and setCounter as props to ‘Counter’
You don’t need ‘reset’ state
I am posting my thoughts about using react (as a beginner), and my solution to the app.
treat the react components as the "view" of the application, and maintain the data and controls in the hooks.
create a custom hook to wrap up all data and controls.
create an instance of the custom hook in the top component - display the data in HTML elements and bound controls to buttons to build the app UI
Here are my codes for this simple UI
UI
useCounter hook
counterController component
counter component
Move "count" state from child component (Counter) to parent
component (CounterController).
Pass count state as prop to child component.
Pass increment and decrement methods from parent to child component through props.
Note: Remove reset state, it's not required anymore.
Sandbox link : https://codesandbox.io/s/infallible-platform-vo4qtv?file=/src/CountController.js
In order to update a prop inside a child component, I was passing a function that updates this prop as a prop to the child component. So the question is that a good approach? and
what is the best approach to update a prop from a child component when using Typescript ?
this is called lifting state up and it is a common approach in React to keep components in sync,
it works by moving the state to the parent component (so you can share it with other siblings) and then passing the state and the event handler as a props
for more details see the official react docs
https://reactjs.org/docs/lifting-state-up.html
In the React docs, it says
By default, when your component’s state or props change, your component will re-render.
I understand for state changes, but I am not sure about when props change. As far as I am aware, props are always passed from the parent component to the child component. And when the parent component re-renders (due to a state change, for example), all child components also re-render (ignoring shouldComponentUpdate). So it seems to me that if the parent component re-renders, all child components will re-render regardless of whether I am passing new props to them or not. If I do pass new props to the child component, the fact the child re-renders is simply because the parent is re-rendering, not because I am passing new props.
Is there a scenario where a parent component passes new props to a child component, causing the child component to re-render, but it is not caused simply by the parent component re-rendering?
Is it possible to see an example where a component will re-render because it receives new props, rather than because the parent is re-rendering (or its own state changed)?
Sorry if this is a basic question, I am new to React.
EDIT: I see that Redux can cause components to re-render by passing new props, I'm curious to know what Redux is doing behind the scenes to achieve this.
To answer the question you ask at the end:
If the child is a PureComponent or wrapped in React.memo it will only re-render if the props change. If the parent re-renders then the component will compare the props it receives and if they're identical to the previously passed props it will not re-render.
If the child is not a PureComponent or wrapped in React.memo then it will re-render any time its parent re-renders.
I‘m not new to react and was asking the same thing. There was an article which made it clear for me: https://thoughtbot.com/blog/react-rendering-misconception
The re-render is needed for diff-checking if DOM updates are necessary. If you‘ve implemented shouldComponentUpdate or wrapped with memo (both returning false), then rerender is skipped.
If a child component is connected using redux or context, then it might rerender even without parent being rerendered.
When you use provider, or HOC, or Redux with mapStateToProps for example, the props are changed from other component injecting props.
Connect middleware of redux is similar to subscription, each child component can directly connect to the store through subscription, and whenever the store changes, the store tries to resync all its connected components. New incoming data to any component comes as props resulting in re-render.
Any component getting changed from outside of its state can be through props only, so it is similar to a parent component passing new data / redux store pushing new data to the component.
how can I make a component to force update its sibling. Currently my component rerenders on componentDidMount but this happens on a selection from a drop down.
Thanks
If you're incurred in this type of problem I suppose you do not use Redux or similar. The easiest way is to lift the state to the common parent component:
Doc ref: https://reactjs.org/docs/lifting-state-up.html
If Comp1 and Comp2 are siblings and Parent is the common parent for the two siblings
You can pass a callback function from Parent to Comp1, whenever Comp1 is updated it can notify the Parent via the callback prop.
In parent you can listen to props change using componentwillreceiveprops and re render the Comp2 using the changed props again passed to it from the Parent.
or in a more complicated appliation set up, you can use redux to store into a global state.
I have two components in my react application, one is parent and the second is the child.
I pass fakedata state as a props to child and then in child component save this as state of child component. But when I change something in child it's affect on parent state and I don't want this I want it's only effect on child state.
This is how I call child component from parent :
<FakeDataAddEditComponent {...this.props} fakedata={{...this.state.fakedata}} />
and in child component this is how I set fakedata props to state :
componentDidMount() {
this.setState({fakedata:{...this.props.fakedata}},()=>{
})
}
but when I change fakedata state in child it's also changend in fakedata of parent and I don't want this.
To answer your question directly, the reason you are seeing this behaviour is because Javascript passes a reference to the original object down the props and to the state of child component. When you update the child component it is the same instance as the parent is holding.
To fix the problem you should use Object.assign to make a copy of the object, however keep in ming that you will run into problems with nested objects.
Also, if parent object mutates the state in any way after the child state changed it will pass old object as props to the child.
In general you're trying to do something you shouldn't do because you will run into trouble.
On a high level you should go for a proper state management solution like Redux of Flux.