2

I don`t know where i do wrong.I cant send data from child to parent. What is wrong here? How can i grab the state from child and send to parent state?

this is the child component

import React from 'react';

export class Child extends React.Component{
  constructor(props) {
    super(props);
    this.state= {
      counter2: 5
    }
  }

  render() {
    return(
      <div>
        <button onClick={this.props.data}>Click me</button><span>{this.state.counter2}</span>
      </div>
    );
  }
}

export default Child;

and i want to update the state in parent component

import React from 'react';
import {Child} from './Child';

export default class Parent extends React.Component{
  constructor(props){
    super(props);
    this.state= {
      counter: 0
    }
  }

  update(){
    this.setState({
      counter: this.props.state.counter2
    });
  }

  render(){
    return(
      <div>
        <span>{this.state.counter}</span>
        <Child data={this.update.bind(this)}/>
      </div>
    );
  }
}

but i have a error: × TypeError: Cannot read property 'counter' of undefined?

i cant understand what i do wrong!

Thank you

TextError
  • 339
  • 3
  • 5
  • 11
  • 1
    What is this `this.props.state.counter` ? – Liam Apr 28 '18 at 13:51
  • Possible duplicate of [How to pass data from child component to its parent in ReactJS?](https://stackoverflow.com/questions/38394015/how-to-pass-data-from-child-component-to-its-parent-in-reactjs) – Ashh Apr 28 '18 at 14:27

2 Answers2

5

Actually, you don't have state property in your Parent's props. You can't get child's state in a such way:

this.props.state.counter2

Props ONLY passed from parent component to child (if you don't use Redux or another state management library).

Nevertheless, you can pass it like this:

Parent component

import React from 'react';
import {Child} from './Child';

export default class Parent extends React.Component{
  constructor(props){
    super(props);
    this.state= {
      counter: 0
    }
  }

  update(value){
    return () => {
       this.setState({
         counter: value
       });
    }
  }

  render(){
    return(
      <div>
        <span>{this.state.counter}</span>
        <Child data={this.update.bind(this)}/>
      </div>
    );
  }
}

Child component

import React from 'react';

export class Child extends React.Component{
  constructor(props) {
    super(props);
    this.state= {
      counter2: 5
    }
  }

  render() {
    return(
      <div>
        <button onClick={this.props.data(this.state.counter2)}>Click me</button><span>{this.state.counter2}</span>
      </div>
    );
  }
}

export default Child;
Denys Kotsur
  • 2,579
  • 2
  • 14
  • 26
2

You are not passing content2 state in the child component correctly

You need to pass it with the button

 <button onClick={()=> this.props.data(this.state.counter2)}>Click me</button><span>{this.state.counter2}</span>

Then in your update function

  update = (data) =>{
    this.setState({
      counter: data
    });
  }

Note: no need to bind update function if you are using arrow function like me.

  <div>
    <span>{this.state.counter}</span>
    <Child data={this.update)}/>
  </div>
Liam
  • 6,517
  • 7
  • 25
  • 47
  • 1
    This won't work. `onClick` handler should take reference for function. In your case it will get `undefined`. – Denys Kotsur Apr 28 '18 at 14:05
  • You are calling the function rather than passing it. – Yuya Apr 28 '18 at 14:12
  • It's not related to binding at all. I'm talking about different thing. You're calling `this.props.data(this.state.counter2)` during rendering. Function `update` is evaluated and returns `undefined` to the event listener. – Denys Kotsur Apr 28 '18 at 14:12
  • Ooh yes I forgot to put arrow function to onClick in the child component – Liam Apr 28 '18 at 14:29
  • Thank you for letting me know :) – Liam Apr 28 '18 at 14:58