0
votes

I have an App parent component, and a child Create component.

I read from other threads in SO that I have to create a method that sets state on the parent component, and pass it to the child as props.

In my case, I have a method called post in parent, and passed to the child Create component, which is called when a button is clicked.

When the button is clicked, turns out that it cant even read state because its undefined. Appreciate any input I could get.

Parent Component

class App extends React.Component {
    state = {
        products: []
    }

    post(name){ //post method to be passed into Create component as props
        return axios.post(`http://localhost:3000/api/products/${uuidv4()}`, {id: uuidv4(), name: name })
        .then(res => this.setState({products: [res.data, ...products]})) //console.log(this.state) will return Cannot read property state of undefined.
        .catch(error => console.log(error));
    }

    render(){
        const {products} = this.state;       
        return( //pass this.post to Create component
            <div>
                <Create post={this.post}/>
            </div>
        )
    }
}

Child Component

class Create extends React.Component {
    state = {
        inputValue: '',
    }

    updateInput(value){
        this.setState({inputValue: value});
    }

    render(){
        const {inputValue} = this.state;
        const {post} = this.props; //destructure post method from App component
        return( // called post method inside the button onClick
        <div className='form'>
            <input type='text' value={inputValue} onChange={(event)=>this.updateInput(event.target.value)}/>
            <button onClick={() => post(inputValue)}>Create</button> 
        </div>
        )
    }
}
2

2 Answers

1
votes

In your parent component change it like this:

<Create post={(input) => {
    this.post(input);
}}/>

The reason you need to do that is that the way post is being invoked in the child component means it's not "scoped" to your parent component.

0
votes
const post = (name) => {
    ....
}

(use an arrow function to not use bind on that function in the component constructor)

<button onClick={() => post(this.state.inputValue)}>Create</button> 

(I think is required this.state to retrieve the inputValue state property)