1

How can I access and set a dynamic e.target.value of a class with setState?

I've tried this.setState({fields[e.target.name]: e.target.value});

class App extends Component  {
  constructor() {
    super();
    this.state = {
      data: [],
      fields: {
        name: ''
      }
    }
  }

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

  render() {
    const { fields } = this.state;
   
    return (
      <>
        <input type="text" name="name" placeholder="name" onChange={this.handleChange} value={fields.name} />
      </>
    )
  }
}

export default App;

  
bird
  • 1,872
  • 1
  • 15
  • 32
totalnoob
  • 2,521
  • 8
  • 35
  • 69
  • 2
    Nested state is anti-pattern in React: components' state should be kept flat, precisely to face the issue you're facing. – Nino Filiu Mar 26 '19 at 22:35

2 Answers2

4

You can't access a state property like this. A possible solution is to create a copy from the fields, modify the value and then set the new state, like below:

handleChange = e => {  
    // The line below creates a copy of the state, using the spread operator
    let fields = { ...this.state.fields };
    fields[e.target.name] =  e.target.value
    this.setState({fields});
}
reisdev
  • 3,215
  • 2
  • 17
  • 38
4

This is a slightly similar to this question. There are two ways to update the object. And as others have said, nesting state like this is an antipattern. This is a good read-up on why.

1- Simplest one:

First create a copy of fields then do the changes in that:

let fields = Object.assign({}, this.state.fields);    //creating copy of object
fields[e.target.name] =  e.target.value               //updating value
this.setState({fields});

Instead of using Object.assign we can also write it like this:

let fields = {...this.state.fields};

2- Using spread operator:

  handleChange = e => {
    e.persist(); //need to make the values persist because of event pooling
    this.setState(prevState => ({
      ...prevState,
      fields: {
        [e.target.name]: e.target.value
      }
    }))
  }
pooya72
  • 1,003
  • 9
  • 15