Search code examples
javascriptreactjsreact-tsx

setState function not working on child component


I have the following code in my React component:

class TheComponent extends Component{

    constructor(props) {

        super(props);

        this.state = {
            a: '',
            b: ''
        };
    }

    output = (data) => {

        this.setState({
            a: data.a,
            b: data.b
        });
    }

    render(){
        return(<ChildrenComponent outputValues={this.output.bind(this)}/>);
    }
}

When I call the output method from the same component, it works perfectly well, and the state is changed successfully. But when I call it from my ChildrenComponent it doesn't work, and the state never changes.

So I've added the following code to the output function in order to find out what's going on: console.log(this.setState). And the result is that the "setState" function is there.

So, if the function setState is properly bound to output, why it doesn't work? And why it does works only when output is called from the current component?`


Solution

  • Your code looks pretty good to me. I think you're just getting a bit confused with what setState does. setState is a built in React function and running console.log(this.setState) will therefore always log a function, specifically that function.

    I'm not sure how you are calling your prop in the child component, but the example below allows the child component to set the parents state to the data object above the render functions return as well as logging the parent state to the console.

    class TheComponent extends Component{
        constructor(props) {
            super(props);
            this.state = {
                a: '',
                b: ''
            };
         }
    
         setValues = (data) => {
            this.setState({
                a: data.a,
                b: data.b
            });
          }
    
         outputValues = () => {
             console.log(this.state);
         }
    
          render(){
            return (
                <ChildrenComponent set={this.setValues} output={this.outputValues}/>
                <p>{this.state.a}</p>
            );
          }
        }
    
    class ChildrenComponent extends Component{
          render() {
            const data = { a: 'foo', b: 'bar' };
            return (
                <button onClick={() => this.props.set(data)}>change parent state</button>
                <button onClick={this.props.outputValues}>console.log parent state</button>
            );
          }
        }