0

I trying to create a table dynamically from the data received from an ajax response in a react app. The loop is created from the response of an ajax request inside the useEffect hook. The problem is that I can't make work the onClick attribute in an anchor tag in a table cell. Below is the code.

res.data.users.forEach(function (user) {
          let row = table.insertRow(rowcnt);
          let cell1 = row.insertCell(0);
          let cell2 = row.insertCell(1);
          let cell3 = row.insertCell(2);
          cell1.innerHTML = user.u_id;
          cell2.innerHTML = user.username;
          cell3.innerHTML = '<a href="javascript:void(0)"><span data-feather="edit"></span></a><a href="javascript:void(0)" onClick={(e) => deleteUser(e, ' + user.id + ')}><span data-feather="trash"></span></a>';
          rowcnt++;
        });

But in the frontend it is showing

enter image description here

Please help.

4
  • You should use createElement and appendChild instead of innerHTML = "element string" for much more readable code. Your onClick is also confusing, what are you trying to do with it? Commented Sep 13, 2021 at 9:46
  • I think you don't use react at it should be, maybe it will be better to set the given data inside a state, and construct your table depending on it... no ? Commented Sep 13, 2021 at 9:49
  • @Jesper Call axios.delete to delete the user. Commented Sep 13, 2021 at 9:52
  • @BENARDPatrick Yes, I am newbie in react Commented Sep 13, 2021 at 9:53

2 Answers 2

3

The "React way" is to use:

  1. state to maintain the data.

  2. map to iterate over the user data held in state and produce array of HTML for each user. Add an id to each tr element.

  3. filter in deleteUser function to filter out the row data where the u_ids don't match the id of the deleted row, and use that array to update the state at which point the component will be re-rendered with the updated state.

const { useState } = React;

function Example({ data }) {

  const [ users, setUsers ] = useState(data.users);

  function deleteUser(id) {
    // Call Axios with the id to delete that item
    const filtered = users.filter(user => user.u_id !== id);
    setUsers(filtered);
  }

  function getRows(users) {
    return users.map(user  => {
      const { u_id, username } = user;
      return (
        <tr key={u_id} id={u_id}>
          <td>{u_id}</td>
          <td>{username}</td>
          <td class="delete">
            <a onClick={() => deleteUser(u_id)}>Delete</a>
          </td>
        </tr>
      )
    });
  }

  return (
    <table>
     {getRows(users)}
    </table>
  );
};

const data = {
  users: [
    {u_id: 1, username: 'Steve'},
    {u_id: 2, username: 'Polly'},
    {u_id: 3, username: 'Brian'},
    {u_id: 4, username: 'Billy Joel'}
  ]
};

ReactDOM.render(
  <Example data={data} />,
  document.getElementById("react")
);
.delete { background-color: red; cursor:pointer; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Sign up to request clarification or add additional context in comments.

6 Comments

In delete function I need to call axios and delete data from database, then refresh the table.
I can only provide a small example of how you should approach the problem. There was no mention of Axios in your question, but just calling Axios within that function with the row id should be very simple.
But the users data is also getting from the axios call. So what is the use of useState?
Because that's how React deals with data. State updates, then the component updates.
But I cannot use useState inside axios. I am getting error React Hook "useState" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks
|
0

I think you should use jsx to instead of innerHTML, like this:

return (
  <table>
    <thead>
      <tr>
        <th>u_id</th>
        <th>usename</th>
        <th>action</th>
      </tr>
    </thead>
    <tbody>
      {res.data.users.map(user => (
        <tr>
          <td>{user.u_id}</td>
          <td>{user.username}</td>
          <td>
            <a onClick={(e) => deleteUser(e, ' + user.id + ')}>delete</a>
          </td>
        </tr>
      )}
    </tbody>
  </table>
)

2 Comments

The loop is created from the response of an ajax request inside the useEffect hook.
The table is already there. I am just creating the rows.

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.