1

I have added sort in my custom table. Sorting is working if I see it in console, It shows the data is getting updated. But my TableBody is not getting updated after once.

Not sure what's happening.

TableWrapper.js

const TableWrapper = ({...props}) => {
  const { tableData, columns } = props;
  const [ visibleData, setVisibleData ] = useState([])
  const sortColumn = (dataIndex, sortOrder) => {
    let sortedData = tableData.data.firstResponse.sort(function(a, b){
      if(a.dataIndex < b.dataIndex) return -1;  // Ascending Order
      if(a.dataIndex > b.dataIndex) return 1;   // Descending Order  
      return 0; // Default
  })
  if (sortOrder === 'desc') {
    sortedData.reverse();
  }    
      console.log(dataIndex, sortOrder)
      console.log(sortedData)
      setVisibleData(sortedData);
  }
    
  return (
    <>
    <table>
      <TableHead headers={columns} isCheckBox={true} isSelectAll={selectAll} selectAllChecked={selectAllChecked} sortColumn={sortColumn} />
      <TableBody rows={tableData} tableData={visibleData} headers={columns} isCheckBox={true} isSelectAll={selectAll} isCheckBoxChecked={selectedCheckBox} />
    </table>
    </>
  );
};

export default TableWrapper;

TableHead.js

const TableHead = ({...props}) => {
  const { headers, isCheckBox, isSelectAll, selectAllChecked, sortColumn } = props;
  const [sortorState, setSortorState] = useState("desc");

  const checkRef = useRef();

  const getSortorState = sortorState => {
    switch (sortorState) {
      case "asc":
        return "desc";
      case "desc":
        return "asc";
      default:
        return "desc";
    }
  };

  const handleSorterChange = (dataIndex, sortOrder) => {
    const updatedSortorState = getSortorState(sortOrder);
    setSortorState(updatedSortorState);
    sortColumn(dataIndex, updatedSortorState)
  };

  return (
    <thead>
        <tr>
          {
            isCheckBox && 
              <th key={`table-header-checkBox`}><input id="select-all-checkBox" type="checkbox" onClick={selectAllChecked} ref={checkRef} /></th>
          }
        {headers.map(item => {
          const { key, field, style, header, sortable} = item
          return (
            <>
            {sortable ? 
              <th
                className={"table-header" + " sortable"}
                onClick={() =>
                  handleSorterChange(field, sortorState)
                }
              >
              <span>{header}</span>
              </th>
            : 
            <th
              key={`table-header-${key}`}
              style={style}>
              {header}
            </th>
            }
            </>
          )})}
        </tr>
    </thead>
  );
};

export default TableHead;

I need some help on this, why It's not getting updated.

Or is there any better way to achieve the sorting?

In the picture, I am trying to sort the first name, If you see the console the data is getting sorted but after one time the table data is not getting updated

enter image description here

1 Answer 1

1

It seems you are mutating the props.tableData.data.firstResponse array, first when .sort is called on it, and again, conditionally when it's reversed. These are both in-place algorithms, meaning they update the array they function over.

Array.prototype.sort

The sort() method sorts the elements of an array in place and returns the sorted array.

Array.prototype.reverse

The reverse() method reverses an array in place. The first array element becomes the last, and the last array element becomes the first.

You will want to first create a shallow copy of the props.tableData.data.firstResponse array to sort and conditionally reverse. It also seems that dataIndex is actually a field property you want to sort by, so it's likely really to be used as a computed property name (there is no dataIndex property so you are comparing undefined values).

const TableWrapper = ({ tableData, columns }) => {
  const [ visibleData, setVisibleData ] = useState([]);

  const sortColumn = (field, sortOrder) => {
    const sortedData = tableData.data.firstResponse
      .slice()                             // <-- create shallow copy of array
      .sort(function(a, b) {
        if(a[field] < b[field]) return -1; // <-_ use computed property
        if(a[field] > b[field]) return 1;  // <-_ use computed property
        return 0;
      });

    if (sortOrder === 'desc') {
      sortedData.reverse();
    } 
    setVisibleData(sortedData);
  }
    
  return (
    <table>
      <TableHead
        headers={columns}
        isCheckBox={true}
        isSelectAll={selectAll}
        selectAllChecked={selectAllChecked}
        sortColumn={sortColumn}
      />
      <TableBody
        rows={tableData}
        tableData={visibleData}
        headers={columns}
        isCheckBox={true}
        isSelectAll={selectAll}
        isCheckBoxChecked={selectedCheckBox}
      />
    </table>
  );
};

A simpler sort toggle function (it can only ever be one or the other, right?):

const getSortorState = sortorState => sortorState === 'asc' ? 'desc' : 'asc';
Sign up to request clarification or add additional context in comments.

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.