Matt Dice
Matt Dice

Reputation: 357

Changing state doesn't remove input values in React

I have a table with different rows (react components). This rows are named service_users. When i click the save button of a row, a registerServiceUser method is called which updates the state in the parent component with a splice function. But after the state changes the input values from the saved row are passed to the next component (see screenshots).

The saved row is here the one with the name Milan den Vliet, after the save (which involves a state change) the value 23:00 and 1,00 are passed to the row of Finn de Dekker.

How can i prevent this behavior?

Before

After

Service user child component code:

return (
  <tr>
    <td style={tdStyle}>{driverIcon}</td>
    <td style={tdStyle}>{this.props.name}</td>
    <td style={tdStyle}>{moment(this.props.startTime).zone('00:00').format('HH:mm')}</td>
    <td><input type="text" onChange={this.handleEndTimeChange} className="form-control" /></td>
    <td><input type="number" onChange={this.handlePauseChange} className="form-control" defaultValue={this.state.pause_time} /></td>
    <td><input type="number" step="any" onChange={this.handleWorkHoursChange} className="form-control" value={this.state.work_hours} /></td>
    <td><input type="number" step="any" onChange={this.handleExtraHoursChange} className="form-control" placeholder="Extra uren"  style={extraHoursBackground} /></td>
    <td style={tdStyle}>{driverField}</td>
    <td style={tdStyle}><a href="#" onClick={this.registerTimesheet} className="btn btn-primary">Opslaan</a></td>
  </tr>
);

After save i update the state with this:

this.setState({ service_users: update(this.state.service_users, {$splice: [[index, 1]]}) });

Upvotes: 1

Views: 3069

Answers (1)

dannyjolie
dannyjolie

Reputation: 11349

I assume that you have a for-loop somewhere to generate the user rows. If this is the case, each row must have a unique key, preferably user ID or something similar. In that case

return (
    <tr>...</tr>
)

must be changed to

return (
    <tr key={this.props.id}>...</tr>
)

Unless you tell React to use a key, it just assumes that the top row is always the same, and just changes the values that have changed.

Update: Take a look at this fiddle. It doesn't do the same thing as your app, but the concepts of changing state and removing the proper elements should apply nevertheless: https://jsfiddle.net/jy0cgemz/

Upvotes: 3

Related Questions