Tarang Hirani
Tarang Hirani

Reputation: 590

react form update state from redux props

I have a component that accepts props form it's parent via redux. This is a multistep form so a user can come back to this section and update the form input fields. However, when I come back to the section and try to clear out the value, because of the way getDerivedStateFromProps is set up, it populates it with the old value.

So, basically, if I have entered the value as 'Test', it cannot completely delete it.

    class StepOne extends Component {
  static getDerivedStateFromProps = (nextProps, prevState) => {
    const {
      stepOne: { name, location, description }
    } = nextProps;
    const shouldUpdate = name === prevState.name || prevState.name === '';
    return shouldUpdate ? { name } : null;
  };

  state = {
    name: '',
    location: '',
    description: ''
  };

  handleChange = (e) => {
    this.setState({ [e.target.name]: e.target.value });
  };

  handleNext = (e) => {
    e.preventDefault();
    const { name, description, location } = this.state;
    this.props.setStepOne({ name, location, description });
  };

  render() {
    return (
      <Col xs={{ size: 8, offset: 2 }}>
        <Col xs='12' className='margin-bottom-60'>
          <label className='header-label' htmlFor='name'>
            Name
          </label>
          <input
            className='form-input'
            placeholder='Whats the conference name?'
            id='name'
            name='name'
            defaultValue={this.props.stepOne.name !== '' ? this.props.stepOne.name : null}
            value={this.state.name}
            onChange={this.handleChange}
          />
        </Col>
        <Col xs='12' className='margin-bottom-60'>
          <label className='header-label' htmlFor='location'>
            Location
          </label>
          <input
            className='form-input'
            placeholder='Where is the conference located?'
            id='location'
            name='location'
            value={this.state.location}
            onChange={this.handleChange}
          />
        </Col>
        <Col xs='12' className='margin-bottom-60'>
          <label className='header-label' htmlFor='description'>
            Description
          </label>
          <input
            className='form-input'
            placeholder='Tell us something more about the conference...'
            type='textarea'
            id='description'
            name='description'
            value={this.state.description}
            onChange={this.handleChange}
          />
        </Col>
        <div
          style={{
            width: '100%',
            position: 'fixed',
            bottom: '0px',
            zIndex: '100',
            textAlign: 'center',
            padding: '10px',
            left: '0px'
          }}
        >
          <NextButton handleClick={this.handleNext} />
        </div>
      </Col>
    );
  }
} 

Upvotes: 0

Views: 374

Answers (1)

Tomasz Mularczyk
Tomasz Mularczyk

Reputation: 36179

Why don't you just initialize state with props? I assume they have the same initial values as in the local state.

state = {
  name: this.props.stepOne.name,
  location: this.props.stepOne.location,
  description: this.props.stepOne.description
};

or less verbose:

state = { ...this.props.stepOne }

Then you don't need getDerivedStateFromProps at all.

Upvotes: 1

Related Questions