Search code examples
reactjsuse-state

How to update component when state in parent class changes?


Parent class (removed some irrelevant code):

class AddCategory extends React.Component{
constructor() {
    super();
    this.state = {
        update: '',
        category_name: ''
    }
}


update(changed) {
    this.setState({
        update: changed,
    })
}

render() {
      const create_category = () => {
        Axios.post('/createCategory', {
            category_name: this.state.category_name,
        }).then((response) => {

        })
      }

      
    return (
        <div>
            //changes the update state to 1 because there was an update
            <button className="btn" onClick={this.update('1'); create_category()}}>Add</button>
        </div>
        )
}
}

export default AddCategory;

Child class (removed some irrelevant code):

class AddSubcategory extends AddCategory {

constructor() {
    super();
    this.state = {
        subcategory_name: '',
        category_id: '',
        result: [],
        is_loading: true
    }
}

set_fetched_data(data, is_fetched) {
    this.setState({
        result: data,
        is_loading: is_fetched
    })
}

//fills the select box with db entries
//need to update the result array every time 'update' state changes
componentDidMount() {
    Axios.get('/categories').then((response) => {
        const category_list = response.data.result;
        this.set_fetched_data(category_list.map(category => <option value={category.id}>{ category.category_name }</option>), false);
    })
}


render() {
    const create_subcategory = () => {
        Axios.post('/createSubcategory', {
            subcategory_name: this.state.subcategory_name,
            category_id: this.state.category_id
        }).then((response) => {

        })
    }

return (
    <div>
        <select name="categories" onChange={(e) => {this.set_category_id(e.target.value)}}>
            <option defaultValue>-</option>
            { !this.state.is_loading && this.state.result }
        </select>
        <input type="text" onChange={(e) => {this.set_subcategory_name(e.target.value)}}/>
        {!this.state.is_loading && <button className="btn" onClick={create_subcategory}>Add</button>}
    </div>
)
}

}

export default AddSubcategory

Need to figure out how to access the 'update' state in the child class + how to listen for changes in the state to keep updating my selectbox - initially I was going to do this with useEffect(), but after reworking both functions into classes I found out that that's not possible.


Solution

  • If you're using classes instead of functions than you cannot use hooks such as useEffect or useContext.

    I highly suggest using react-redux for a cross application state management. You'll need to do some setup but you'll get a shared state accessible by all components - no matter the level.

    Here's a step by step for a basic setup on a react project.