Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / React

Update State of a Component from Another in React

5.00/5 (1 vote)
18 Nov 2017CPOL1 min read 149.5K  
How to change state of child from parent, state of parent from child and state of sibling from another sibling

Introduction

As the title mention, this tip will discuss how to update the state of one component from another component in ReactJS. Components may have parent-child relation or sibling relation, there might be a hierarchy of children also, so this article will focus on mainly three relations - parent to child, child to parent and sibling to sibling.

Parent-Child

Parent to Child

We just have to write a function globally and bind it to the child. This function will be responsible for updating the state. Let's see how:

JavaScript
//this is the function responsible to update the state
function updateState(text){
    this.setState({text})
}
JavaScript
//binding 'updateState' function with the child... 
//now calling 'updateState' will update the child's state
constructor(props) {
    super(props)
    this.state = {
        text: "Initial State"
    }
    updateState = updateState.bind(this)
}

The full code is as follows:

JavaScript
import React, { Component } from 'react';
import { style, primaryColor, secondaryColor } from '../style';

function updateState(text){
    this.setState({text})
}

//passing state from parent to child
class Child1 extends Component {
    constructor(props) {
        super(props)
        this.state = {
            text: "Initial State"
        }
        updateState = updateState.bind(this)
    }
    render() {
        return (
            <div>
                <div style={{ ...style.topLabel, color: primaryColor }}>I am Child</div>
                <div style={style.label}>{this.state.text}</div>
            </div>
        )
    }
}

class Parent extends Component {
    constructor(props) {
        super(props)
    }
    updateChild(text) {
        updateState(text)
    }
    render() {
        return (
            <div>
                <div style={{ ...style.topLabel, color: secondaryColor }}>I am Parent</div>
                <input style={style.textBox} type="text" 
                 placeholder="Write text" onChange={(e) => this.updateChild(e.target.value)} />
                <Child1 />
            </div>
        )
    }
}

export default Parent;

Child to Parent

It's very easy to update the state of the parent from any child, you just have to pass a callback function as props to that child and whenever it needs to update the state of parent, the function will be called. Let's see how it works:

JavaScript
class Child extends Component {
    render() {
        return (
            <div>
                <div style={{ ...style.topLabel, color: primaryColor }}>I am Child</div>
                <input style={style.textBox} type="text" 
                 placeholder="Write text" onChange={(e) => this.props.updateTextCB(e.target.value)} />
            </div>
        )
    }
}

class Parent extends Component {
    constructor(props) {
        super(props)
        this.state = {text: "Initial Text"}
        this.updateText1 = this.updateText1
    }
    updateText1 = (text) => {this.setState({ text })}
    render() {
        return (
            <div>
                <div>I am Parent</div>
                <div style={style.label}>{this.state.text}</div>
                <Child updateTextCB={this.updateText1} />
            </div>
        )
    }
}

Alternate Method

We can create a function outside the parent class, bind it to the parent and call the function from child class when needed, similar to the previous case (parent to child). Let's see an example:

JavaScript
//
class Child extends Component {
    constructor(props) {
        super(props)
    }
    render() {
        return (
            <div>
                <div>I am Child</div>
                <input style={style.textBox} type="text" placeholder="Write text" 
                 onChange={(e) => updateText2(e.target.value)} />
            </div>
        )
    }
}

function updateText2(text) {
    this.setState({ text })
}

class Parent extends Component {
    constructor(props) {
        super(props)
        this.state = {
            text: "Initial Text"
        }
        updateText2 = updateText2.bind(this)
    }
    updateText1 = (text) => {
        this.setState({ text })
    }

    render() {
        return (
            <div>
                <div>I am Parent</div>
                <div style={style.label}>{this.state.text}</div>
                <Child />
             </div>
        )
    }
}

Sibling-Sibling

Similar to the 'parent to child' case, we will create a function and bind it the interested class and whenever needed, we will call that function from any other component. Let's have a look at one example:

JavaScript
class Sibling1 extends Component {
    render() {
        return (
            <div>
                <div style={{ ...style.topLabel, color: secondaryColor }}>I am Sibling 1</div>
                <input style={style.textBox} type="text" 
                 placeholder="Write text" onChange={(e) => updateText(e.target.value)} />
            </div>
        )
    }
}

function updateText(text) {
    this.setState({text})
}

class Sibling2 extends Component {
    constructor(props) {
        super(props)
        this.state = {
            text: "Initial State"
        }
        updateText = updateText.bind(this)
    }
    render() {
        return (
            <div>
                <div style={{ ...style.topLabel, color: primaryColor }}>I am Sibling 2</div>
                <div style={style.label}>{this.state.text}</div>
            </div>
        )
    }
}

class Example3 extends Component {
    render() {
        return (
            <div>
                <Sibling1 />
                <Sibling2 />
            </div>
        )
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)