0

In my react hooks component I am rendering data from an array of objects.

const lineInfo = [
  {
    id: '001',
    line: 's-1125026',
    arrival: '7:30',
    departure: '8:00',
    authorization: 'User 1',

  },
  {
    id: '002',
    line: 's-1125027',
    arrival: '8:01',
    departure: '8:50',
    authorization: 'User 1',
  },

In the .map() I'm returning data using this data:

       <div>
         {lineInfo.map((line) => (
              <Row key={`line_${line.id}`}>

 // remaining code removed for length

The list returns fine, so now I am trying to remove a row from the list. Remove func

  const [list, setList] = useState(lineInfo);

  function handleRemove(id) {
    console.log('id' id);
    const newList = list.filter((line) => line.id !== id);
    setList(newList);
  }

Remove Button

        <Button
          className={style.close_button}
          onClick={() => handleRemove(line.id)}
         >
           <img src={close} alt="trash" />
        </Button>
</Row>

The problem I am running into is that in my console log, is that only the line.id is being removed from the array instead of the whole row of data.

  1. How do I remove all the data belonging to a particular id?
  2. Even though the console log shows that the text is removed, why is the text that is displayed in my row not removed from the view?

I'm not too familiar with hooks and have only been able to find examples of my particular problem with class components. Thanks in advance.

1
  • maybe a codesandbox? Commented Jul 1, 2020 at 10:42

2 Answers 2

2

You should display the defined state with the hook. in this case the list , and not the lineInfo.

 <div>
   {list.map((line) => (
     <Row key={`line_${line.id}`}>

 // remaining code removed for length
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. I totally didn't realize that because I used lineInfo in my the useState constant that I would need to change it in the map also.
You need to change it, because in react scope, the non *useHook* variables, are not reactive
1

You should not render lineInfo, render the list from local state instead:

const { useState, useCallback } = React;
const lineInfo = [
  {
    id: '001',
    line: 's-1125026',
    arrival: '7:30',
    departure: '8:00',
    authorization: 'User 1',
  },
  {
    id: '002',
    line: 's-1125027',
    arrival: '8:01',
    departure: '8:50',
    authorization: 'User 1',
  },
];
//make row pure component using React.memo
const Row = React.memo(function Row({ item, remove }) {
  return (
    <div>
      <pre>{JSON.stringify(item, undefined, 2)}</pre>
      <button onClick={() => remove(item.id)}>
        remove
      </button>
    </div>
  );
});

const App = () => {
  const [list, setList] = useState(lineInfo);
  //make remove a callback that is only created
  //  on App mount using useCallback with no dependencies
  const remove = useCallback(
    (removeId) =>
      //pass callback to setList so list is not a dependency
      //  of this callback
      setList((list) =>
        list.filter(({ id }) => id !== removeId)
      ),
    []
  );

  return (
    <ul>
      {list.map((line) => (
        <Row
          key={`line_${line.id}`}
          item={line}
          remove={remove}
        />
      ))}
    </ul>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>


<div id="root"></div>

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.