crash springfield
crash springfield

Reputation: 1082

Can't set React state with defaultValue

I'm trying to make the user profile editable in my component. Right now, when the user clicks "edit," the profile is replaced with a form that has the values they typed in as defaults. However, if they update only one field, the others get rewritten with blank values instead of passing the default value to the state.

Is there a way to pass the defaultValue to the state? I've tried value={} too but then the value doesn't change at all.

I'm trying to avoid having an "Edit" button for each input.

class AccountEditor extends Component {
  constructor() {
    super()
    this.state = {
      isEditing: false,
      profile: {
        firstName: '',
        lastName: '',
        city: '',
        email: '',
        bio: '',
      }
    }
  }

  toggleEdit(event) {
    event.preventDefault()
    this.setState({
      isEditing: !this.state.isEditing
    })
  }

  updateProfile(event) {
    let updatedProfile = Object.assign({}, this.state.profile)
    updatedProfile[event.target.id] = event.target.value

    this.setState({
      profile: updatedProfile
    }
  }

  submitUpdate(event) {
    event.preventDefault()
    this.props.onUpdate(this.state.profile)
    this.setState({
      isEditing: !this.state.isEditing
    })
  }

  render() {
    let profile = this.props.profile
    let content = null

    if (this.state.isEditing == true) {
      content = (
        <div>
          <input
            id="firstName"
            onChange={this.updateProfile.bind(this)}
            defaultValue={profile.firstName} />
          <br />
          <input
            id="lastName"
            onChange={this.updateProfile.bind(this)}
            defaultValue={profile.lastName} />
          <br />
          <input
            id="city"
            onChange={this.updateProfile.bind(this)}
            defaultValue={profile.city} />
          <br />
          <input
            id="email"
            onChange={this.updateProfile.bind(this)}
            defaultValue={profile.email} />
          <br />
          <textarea
            id="bio"
            onChange={this.updateProfile.bind(this)}
            defaultValue={profile.bio} />
          <br />
          <button onClick={this.submitUpdate.bind(this)}>Done</button>
        </div>
      )
    } else {
      content = (
        <div>
          <h4>Name: </h4>
          <span>{profile.firstName}</span>
          <span>{profile.lastName}</span><br/>
          <h4>City: </h4>
          <span>{profile.city}</span><br/>
          <h4>Bio :</h4>
          <p>{profile.bio}</p><br />
          <button onClick={this.toggleEdit.bind(this)}>Edit</button>
        </div>
      )
    }

    return (
      <div>
        {content}
      </div>
    )
  }
}

export default AccountEditor

Upvotes: 4

Views: 12098

Answers (1)

Deividas
Deividas

Reputation: 6507

You should replace defaultValue with value = { this.state.someProp }. So an example with your code would be

constructor(props) {
    super(props)
    this.state = {
      isEditing: false,
      profile: props.profile // Setting up the initial data from the passed prop
    }
  }

and

<input id="firstName"
       onChange={ this.updateProfile.bind(this) }
       value={ this.state.profile.firstName } />

More about using react with form elements in these docs.

Upvotes: 7

Related Questions