Search code examples
reactjsreact-propsreact-component

Updating parent component without a call back function in react js


I was doing a POC coding on React js with component which has a Child component.As far as I know, there was no other way to update the state of parent from child except through a call back function from the child to the parent component. In my case, I tried to pass the state of the parent to the child and set them on the child state directly as props (this.props.).I noticed that if I change the state of the child, the state of the parent is also getting updated. I'm bit confused. Could somebody please help ? Here is my code.

index.js

ReactDOM.render(<App2/>,document.getElementById('root'));

App2.js - Parent component

import React from 'react'
import ScreenTest From './ScreenTest'

class App2 extends React.Component{

 state={
   address : {
         houseName:'1234 House Name'
   }
}

render(){
 return(
    <ScreenTest parentState={this.state} address={this.state.address} /> 
  )
}

}

ScreenTest.jsx - Child Component

import React from 'react';

class ScreenTest extends React.Component{
 state={
    parentState: this.props.parentState,
    address : this.props.address
}

clickButton = () =>{
  let addressTemp = this.state.address;
  addressTemp.city= "Kerala";
  this.setState({
   address:addressTemp
  })
}

render(){
  console.log("To view the state when the screen renders",this.state)
  return(
       <a onClick={this.clickButton}>Click me to update the state and re render </a>
  )
}

}

Code explanation: I am invoking App2 component which has a child Component ScreenTest. I pass the currentState of App2 to ScreenTest. In ScreenTest i set the state from the values passed as props. In ScreenTest I have an anchor tag when clicked, updates the "address" state of ScreenTest and re render Screen. When the screen is re rendered , i check the state to see that parentState is also getting updated with new Address (i.e city is added to it).

Please tell me how the parentState is also getting affected by it. I'm bit confused.


Solution

  • You must note that when docs say that in order to update parent state from child, you must make use of callback and let the parent update its state, its the ideal and the correct way of doing it

    In your code you are accidently updating the parent state you mutate the state by calling

      let addressTemp = this.state.address;
      addressTemp.city= "Kerala";
    

    In Javascript, object are used by reference and updating a property in object directly will update it for anyone using that reference

    So when you assign props to state in constructor like below

    state={
        parentState: this.props.parentState,
        address : this.props.address
    }
    

    The state properties hold the reference of props object and hence the props also get updated when you mutate the state property by updating addressTemp state

    The ideal way to update state is to clone it and then make changes so that you avoid unexpected issues

    clickButton = () =>{
      let addressTemp = {...this.state.address}; // clone state
      addressTemp.city= "Kerala";
      this.setState({
       address:addressTemp
      })
    }