Champer Wu
Champer Wu

Reputation: 1271

Why my onChange do not work when state have object on ReactJs

I tried to build a app use ReactJS by ES6

class MyApp extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      employee:{
      name: 'hello',
      birthday: ''
      },
      price: ''
    }
    this.handleValueChange = this.handleValueChange.bind(this);
  }
  handleValueChange(event){
    valueName = event.target.name
    this.setState({[valueName]: event.target.value});
  };
  render(){
    return(
    <form>
      <input type="text" placeholder="name" value={this.state.employee.name} onChange={this.handleValueChange} name="name"/>
      <input type="text" placeholder="name" value={this.state.price} onChange={this.handleValueChange} name="price"/>
    </form>
    )
  }
}

As my Code, I used handleVauleChange in onChange event to change the default state of the input html tag.If the data in this.state is object(like employee), the handleVauleChange function will not work, but the data is like price, it will work fine.

Why has it happened?

Upvotes: 0

Views: 89

Answers (3)

vijay
vijay

Reputation: 631

created jsbin:

http://jsbin.com/vopixexixe/edit?js,console,output#J:L14

In name input your setting input value from this.state.employee.name which is "hello" but on change your setting changed value to this.state.name

but in case of price your setting input value from this.state.price and updating to this.state.price, so value is reflecting.

Upvotes: 1

jpdelatorre
jpdelatorre

Reputation: 3593

Your setState for the name input should be like this...

this.setState({
    employee: {
        [valueName]: event.target.value
    }
});

Not sure how dynamic the state structure you need but for one level deep structure, you can do something like this...

handleValueChange(event) {
    const valueName = event.target.name;
    const parent = valueName.indexOf('.') !== -1 ? valueName.split('.')[0] : false;
    if (parent) {
        this.setState({
            [parent]: {
                [valueName]: event.target.value
            }
        });
    } else {
        this.setState({
            [valueName]: event.target.value
        });
    }
}

and on your input fields...

<input 
    type="text" 
    placeholder="name" 
    name="employee.name"
    value={this.state.employee.name} 
    onChange={this.handleValueChange} />
<input 
    type="text" 
    placeholder="price" 
    name="price"
    value={this.state.price} 
    onChange={this.handleValueChange} />

Upvotes: 1

marcinrek
marcinrek

Reputation: 339

In case of "name" you edit state.name and you want to edit state.employee.name I think

Upvotes: 0

Related Questions