2

I want to change input text value using state and React value property and also make the field editable.

My component's constructor:

constructor(props) {
    super(props);

    // States
    this.state = {
        value: this.props.object.subtext
    };

    this._handleChange = this._handleChange.bind(this);
}

My render() function:

return (
    <input
        type={this.props.object.type}
        value={this.props.object.subtext}
        onChange={this._handleChange}
    />
);

componentDidUpdate() function:

componentDidUpdate() {
    if (this.state.value !== this.props.object.subtext) {
        this.setState({value: this.props.object.subtext});
    }
}

And for _handleChange(e) function:

_handleChange(e) {
    this.props.object.subtext = e.target.value;
    this.componentDidUpdate(); // not sure it's right or not
}

The code works fine, but I'm a little bit unsure that was the best practice or not because I recalled this.componentDidUpdate() manually inside the event handler function.

I did it to fix my previous bug which is the value of input component won't be updated when the state was changed.

I want to know whether what I'm doing is right or not, any comments or answers will be appreciated.

1
  • 1
    do not change props inside component. _handleChange should pass value to the parent component callback Commented May 19, 2017 at 16:07

3 Answers 3

2

No its not a good practise to call the lifecycle function yourself

Rather than that, you can modify your state props like

constructor(props) {
    super(props);

    // States
    this.state = {
        value: this.props.object.subtext
    };

    this._handleChange = this._handleChange.bind(this);
}
componentWillReceiveProps(nextProps) {
    if (this.props.object.subtext !== nextProps.object.subtext) {
        this.setState({value: nextProps.object.subtext});
    }
}
_handleChange(e) {

    //cal a parent compoent function
    this.props.changeProps(e.target.value);
}
Sign up to request clarification or add additional context in comments.

5 Comments

Where's the this.props.changeProps() come from?
Define a function changeProps in the parent component which changes the value object.subtext passed down to child and pass this function to you child functin like <Child changeProps={(val)=> {this.changeProps(val)}} />
But, the input component become immutable now.
This is the correct way to do it and this.props.object.subtext = e.target.value;, is wrong,
Does this.props.object.subtext = e.target.value; make it become immutable?
1

As you suspected calling componentDidUpdate is bad idea. You can change your state in _handleChange and remove componentDidUpdate call.

Comments

1

You can setState in _handleChange. You'll need to bind to this.state.value for your local state, though, opposed to this.props.object.subtext. Observe the following...

constructor(props) {
  super(props);

  this.state = {
    value: this.props.object.subtext
  };
}

_handleChange(e) {
  this.setState({
    value: e.target.value
  });
}

render() {
  return (
    <input
      type={this.props.object.type}
      value={this.state.value}
      onChange={this._handleChange.bind(this)}
    />
  );
}

Alternatively, if you're looking for a props only solution without local state, I suggest giving redux a look.

2 Comments

I tried this, but the input text value was not updated when state was changed.
Should work just fine. Granted, while not TypeScript or a class, here is a working sample exactly replicated - JSFiddle example

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.