2

I am learning to use hooks with react and trying to make a simple website where you write 2 values and add them to a list. Each item in the list got a delete button.

For some reason, when I am adding more than 2 rows the problem seems to start. If I for example add 2 rows, and press delete on the old rows that got loaded on start - it is either deleting them or replacing them with same values as the new rows.

Not sure what I am doing wrong here since the delete works until I add more than +2 rows directly at the start.

Kinda hard to explain, but I've made a sandbox where it's easier to see the problem.

Delete & add functions:

  const deleteRow = async (index, e) => {
    var data = testArr;
    data.splice(index, 1);

    setTestArr([...data]);
  };

  const addRow = async e => {
    var obj = {
      id: 1,
      start: inputFrom,
      stop: inputTo
    };

    var data = testArr;
    data.push(obj);

    setTestArr([...data]);
  };

Mapping function:

{testArr.map((item, index) => (
        <div key={item.id} className="col-12">
          <div className="control-group mb-1">
            <span className="mr-2">
              {item.start} - {item.stop}
            </span>
            <input
              type="button"
              className="btn btn-light"
              value="Delete row"
              onClick={e => deleteRow(index, e)}
            />
          </div>
        </div>
      ))}

Sandbox:

Edit creact-hooks-usestate-nk4cl

3 Answers 3

3

first, you might not use var keyword and instead use ES const || let, for making sure you are not encountering unexpected side effects because of JS hoisting,

second -

var data = testArr;
data.splice(index, 1);

is illegal move, cause data isn't a different place in memory from the state, it is just a pointer on it, and therefore you modify state outside setState

the first option is to shallow copy state

let data = [...testArr];

or directly implement the logic inside setState

// delete
setTestArr(prev => prev.filter((item, i) => i != index ));
// add
setTestArr(prev => [...prev, obj]);
Sign up to request clarification or add additional context in comments.

Comments

3

Try with these functions:

const deleteRow = async (index, e) => {
  var data = [...testArr];
  data.splice(index, 1);
  setTestArr(data);
};

and

const addRow = async e => {
  setTestArr([{
   id: 1,
   start: inputFrom,
   stop: inputTo
 },...testArr]);
};

I sugest you tu use useCallback t define these.

Comments

3

I would use this delete function:

  const deleteRow = (index, e) => {
    setTestArr(prev => {
      
      return prev.filter((e, i) => i !== index);
    });
  };

Instead of mutating the data, just filtering out, the index what we dont needed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.