Home > other >  How to update state of one component in another in react class component. Save Functionality
How to update state of one component in another in react class component. Save Functionality

Time:01-29

How to update state of one component in another in react class component.

I have two class in reacts.

MyComponent and MyContainer.

export default class MyContainer extends BaseComponent{
    constructor(props: any) {
        super(props, {
            status : false, 
            nameValue :"",
            contentValue : ""
        });
    }
    componentDidMount = () => {
        console.log(this.state.status);
    };
    save = () => {
        console.log("Hello I am Save");
        let obj: object = {
            nameValue: this.state.nameValue, // here I am getting empty string
            templateValue: this.state.contentValue
        };
        // API Call
    };
    render() {
        return (
            <div>
                <MyComponent
                    nameValue = {this.state.nameValue} 
                    contentValue = {this.state.contentValue} 
                ></MyComponent>   
                <div >
                    <button  type="button"  onClick={this.save} >Save</button>
                </div>
            </div>
        );
    }
}

MyComponent

export default class MyComponent extends BaseComponent{
    constructor(props: any) {
        super(props, {});
        this.state = {
            nameValue : props.nameValue ? props.nameValue : "",
            contentValue : props.contentValue ? props.contentValue : "",
            status : false
            
           
        }
    }
    componentDidMount = () => {
        console.log("MOUNTING");
    };

    fieldChange = (id:String, value : String) =>{
        if(id === "content"){
            this.setState({nameValue:value});
        }else{
            this.setState({contentValue:value});
        }
    }
     

    render() {
        return (
            <div>
                <div className="form-group">
                    <input id="name" onChange={(e) => {this.fieldChange(e)}}></input>
                    <input  id = "content"  onChange={(e) => {this.fieldChange(e)}} ></input>
                </div>
            </div>
        );
    }
}

In MyComponent I have placed two input field where on change I am changing the state.

Save button I have in MyContainer. In save button I am not able to read the value of MyComponent. What is the best way to achieve that.

CodePudding user response:

You should be updating your state in MyContainer for save to have visibility of the state changes. Each component gets its own state, which makes MyComponent's state unique to that of MyContainer. What you should be doing is keeping the state in your parent/container component, and then passing it down as props (rather than duplicating it in your child). To do this, move fieldChange up to the MyContainer function, and remove the duplicate nameValue and contentValue state within MyComponent. See code commennts for further details:

export default class MyContainer extends BaseComponent{
    ... 

    fieldChange = (id:String, value : String) =>{
        if(id === "content"){
            this.setState({nameValue: value});
        } else {
            this.setState({contentValue: value});
        }
    }

    render() {
        return (
            <div>
                <MyComponent
                    nameValue={this.state.nameValue} 
                    contentValue={this.state.contentValue}
                    onFieldChange={this.fieldChange} /* <---- Pass the function down to `MyComponent` */
                /> 
                ...
            </div>
        );
    }
}

Then in MyComponent, call this.props.onFieldChange:

export default class MyComponent extends BaseComponent{
    // !! this constructor can be removed as no state is being initialized anymore !!
    constructor(props: any) {
        super(props);
        // removed state as we're using the state from `MyContainer`
    }

    componentDidMount = () => {
        console.log("MOUNTING");
    };

    render() {
        return (
            <div>
                <div className="form-group">
                    <input id="name" onChange={(e) => {this.props.fieldChange(e)}} /> /* <--- Change to `this.props.fieldChange()`. `<input />` is a self-closing tag.
                    <input  id = "content"  onChange={(e) => {this.props.fieldChange(e)}} />
                </div>
            </div>
        );
    }
}

Some additional notes:

  • If your component doesn't use this.props.children, then you should call it as <MyComponent ... props ... /> not <MyComponent ... props ...></MyComponent>
  • Your if-statement in your fieldChange looks reversed and should be checking if(id === "name"). I'm assuming this is an error in your question.
  • You're only passing one argument to fieldChange in your example code. I'm again assuming this in an error in your question.
  • Related