A
A
Arthur2019-08-04 00:30:06
JavaScript
Arthur, 2019-08-04 00:30:06

How to properly handle react controlled component?

Hello everyone, could you tell me the best way to handle a controlled component in React?
There is a table with data, some of the cells of which contain changeable data, for example, inputs, checkboxes.
Now I create handlers for each cell being changed, passing the id of the line being edited to the handler, then I find this line in the state and change the data in it.
checkbox handler looks like this

limitSwitchHandler = rowId => {
    this.setState(({data}) => {
      const idx = data.findIndex(el => el.id === rowId);
      const oldRow = data[idx];
      const newRow = {...oldRow, autoLimit: !oldRow.autoLimit};

      const newArray = [
        ...data.slice(0, idx),
        newRow,
        ...data.slice(idx + 1),
      ];
      return {
        data: newArray,
      }
    });
  };

then in the component i call it like this
<Switch
  checked={element.autoLimit}
  onChange={() => this.limitSwitchHandler(row.id)}
/>;

But when it came to the input, I did not understand how to get its value with this approach. And I read that creating a function every time is not good, but it’s better to do it this way, then I managed to take value, but then how can I easily understand in which line the changes occurred? to keep in date attribute id of a line? __________ UPDATE solved the problem like this
onChange={this.limitSwitchHandler}
limitPerDayHandler = (rowId) => (e) => {
    e.persist();
    console.log(e.target.value);
    this.setState(({data}) => {
      const idx = data.findIndex(el => el.id === rowId);
      const oldRow = data[idx];
      const newRow = {...oldRow, limitPerDay: e.target.value};

      const newArray = [
        ...data.slice(0, idx),
        newRow,
        ...data.slice(idx + 1),
      ];
      return {
        data: newArray,
      }
    });
  };

with a call to the input component like this
<TextInput
          name="limitPerDay"
          value={element.limitPerDay}
          onChange={this.limitPerDayHandler(element.id)}
        />;

but I didn't quite understand how and why e.persist() helped me;

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2019-08-04
@cloudz

Synthetic events cannot be used asynchronously, e.persist() releases the event from the pool and it is not cleared, so all values ​​are preserved at the time the asynchronous call is made.
Your problem was solved like this:
In your solution, it is more correct to name the handler:
since technically the call is not a handler, but returns one.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question