React not updating component props?

- 1 answer

Ad

It seems that my component props are not updated the way I thought they ought to be.

var AdditionalInfoBlock = React.createClass({

    getInitialState: function() {
        return ({
            comment: this.props.comment
        });
    },

    onCommentChange: function(e) {
        this.setState({comment: e.target.value});
        this.props.onCommentChange(e);
    },

    render: function() {
        return (
            <ToolBlock>
                <div className="container">
                    <form>
                        <textarea value={this.props.comment} onChange={this.onCommentChange} />
                    </form>
                </div>
            </ToolBlock>
        );
    }
};

var MainTool = React.createClass({

    getInitialState: function () {
        return {
            comment: undefined
        };
    },

    restart: function (e) {
        e && e.preventDefault && e.preventDefault();
        this.setState(this.getInitialState());
    },

    onCommentChange: function(e) {
        this.setState({
            comment: e.target.value
        });
    },

    render: function() {
        return (
            <div>
                <AdditionalInfoBlock comment={this.state.comment}
                                     onCommentChange={this.onCommentChange} />
            </div>
        );
    }
};

What I want this code to do is basically hold the comment's value until I post it and call restart - then it should reset the value in both AdditionalInfoBlock and MainTool. At the moment after restart is called when I console.log() the state of MainTool, the comment value is undefined. However, if I log AdditionalInfoBlock state and/or props, then the comment value is not reset in neither of those.

(PS. This is obviously a short version of the code, hopefully only incorporating the relevant bits. Although restart is not called in this excerpt, it doesn't mean that I have forgotten to call it at all :))

Ad

Answer

Ad

Since you're handling the same state on both components MainTool and AdditionalInfoBlock, finding value of the comment can get confusing. While you're listening for the comment change, you're setting the state on both components.

The changed state in your parent component MainTool is passing the props to the child AdditionalInfoBlock. getInitialState is invoked once before mounting (getInitialState documentation). Therefore, the passed on property is not handled by you child component on succeeding updates. By using componentWillReceiveProps, you will be able to handle the props sent by MainTool.

var AdditionalInfoBlock = React.createClass({
    ...

    componentWillReceiveProps(nextProps) {
            this.setState({comment: nextProps.comment});
    },

Working Code:https://jsfiddle.net/ta8y1w1m/1/

Ad
source: stackoverflow.com
Ad