George
George

Reputation: 69

React.js: Why child component change parent state?

Why in this example child component changing parent component state? According to the Facebook(react.js) docs State is similar to props, but it is private and fully controlled by the component.

codepen example

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {data: this.props.data};
  }

  handleChange(event) {
    let updatedData = Object.assign({}, this.state.data);
    updatedData[event.target.name][event.target.dataset.lang] = event.target.value;

    this.setState({
      data: updatedData
    });
  }

  render() {
    return (
      <form>
          {Object.keys(this.props.data.titles).map((l, index) => 
          <input type="text" name="titles" data-lang={l} value={this.state.data.titles[l]} onChange={this.handleChange.bind(this)} />
          )}
      </form>
    );
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      images: [{"titles": {"en": "deluxe1500x930.jpg"}
      }],
      count: 1
    };
  }

  render() {
    return (
        <div>
          {Object.keys(this.state.images).map((x,index) => 
            <div>
              {this.state.images[x].titles.en}
              <NameForm data={this.state.images[x]} />
              <button onClick={(() => {this.setState({ count: 2 })}).bind(this)}>test</button>
            </div>
          )}
        </div>
    )
  }
}

Upvotes: 0

Views: 713

Answers (1)

omri_saadon
omri_saadon

Reputation: 10631

Because you set the state with this.props.data. the this.props.data came from the parent, therefore when it's changing so the state changes as well.

The solution is simple, just set the state with new value (copied from this.props.data) by using the spread operator instead of using the same reference.

this.state = {data: ...this.props.data};

Upvotes: 4

Related Questions