Search code examples
reactjsreact-hooksreact-functional-component

Changes are not reflecting in the UI after updating the state in react functional component


. I'm trying to sort the data by name and age when clicked on the header of the column. Data is getting sorted but not reflecting in the UI. I'm sharing the code snippet, Someone please help me out

import './App.css';
import { useState } from 'react';

function App() {
  const [names, setNames] = useState([{ name: 'John', age: 23 }, { name: 'Mary', age: 31 }, { name: 'Anna', age: 18 }, { name: 'Mark', age: 21 }])
  function sort(sortBy) {
    if (sortBy == 'name') {
      names.sort((a, b) => {
        if (a.name > b.name)
          return 1
        else return -1
      })
      setNames(names)
    } else if (sortBy == 'age') {
      names.sort((a, b) => { return b.age - a.age })
      setNames(names)
    }
  }
  return (
    <div>
      <table>
        <tr>
          <th><span style={{ cursor: 'pointer' }} onClick={() => { sort('name') }}>Name</span></th>
          <th><span style={{ cursor: 'pointer' }} onClick={() => { sort('age') }}>Age</span></th>
        </tr>
        {names.map((data) => {
          return (<tr>
            <td> {data.name}  </td>
            <td> {data.age}  </td>
          </tr>)
        })}
      </table>
    </div>
  );
}

export default App;


Solution

  • You are directly modifying the names state variable, therefore React is not able to update the state since the reference to the array is going to be the same. Instead of directly modifying the names array, create a new array when updating the state variable

    function App() {
      const [names, setNames] = useState([{ name: 'John', age: 23 }, { name: 'Mary', age: 31 }, { name: 'Anna', age: 18 }, { name: 'Mark', age: 21 }])
      function sort(sortBy) {
        if (sortBy == 'name') {
          names.sort((a, b) => {
            if (a.name > b.name)
              return 1
            else return -1
          })
          setNames([...names]) // new array
        } else if (sortBy == 'age') {
          names.sort((a, b) => { return b.age - a.age })
          setNames([...names]) // new array
        }
      }
      return (
        <div>
          <table>
            <tr>
              <th><span style={{ cursor: 'pointer' }} onClick={() => { sort('name') }}>Name</span></th>
              <th><span style={{ cursor: 'pointer' }} onClick={() => { sort('age') }}>Age</span></th>
            </tr>
            {names.map((data) => {
              return (<tr>
                <td> {data.name}  </td>
                <td> {data.age}  </td>
              </tr>)
            })}
          </table>
        </div>
      );
    }
    
    export default App;