React.js Table 使用动态数据排序

React.js Table Sorting with Dynamic Data

一些动态数据有两个不同的 API 服务端点,如下所示。

// from API Service A, All value are realtime changing
{
 stack : 10
 over : 2
 flow : 4
}
// from API Service B, All value are realtime changing
{
 stack : 4
 over : 1
 flow : 2
}

来自两个不同API服务的key是相同的,但是实时变化的值是不同的。

所以我想用 table 来标记这些差异。

我用 react.js 编码显示此数据 table,如下所示。

import { useState, useEffect } from 'react';
function App(){
 const [commonKey, setCommonKey] = useState([stack, over, flow]);
 const [dataA, setDataA] = useState({});
 const [dataB, setDataB] = useState({});

 useEffect(()=> {
  // ...periodically fetch data from API Service A and setDataA(response)
  // ...periodically fetch data from API Service B and setDataB(response)
 } ,[]);

 return (
 <>
  <table>
   <thead>
    <th>key</th>
    <th>valueA</th>
    <th>valueB</th>
    <th>A-B</th> // sorting function needed by this field value(A minus B).
   </thead>
   <tbody>
    commonKey.map((keyField)=>{
     <Mytr key={keyField} keyField={keyField} dataA={dataA[keyField]} dataB={dataB[keyField]} />
    });
   </tbody>
  </table>
 </>
)}

function Mytr({keyField, dataA, dataB}){
 return (
 <>
  <tr>
   <td>{keyField}</td>
   <td>{dataA}</td>
   <td>{dataB}</td>
   <td>{dataA - dataB}</td> // sorting function needed by this field value.
  </tr>
 </>
)}

export default App;

在这种情况下如何添加按 A-B 值函数排序

p.s对不起我的英语不好。

您可以 sort useEffect 挂钩中的 commonKey,如下所示。

  useEffect(() => {
    // ...periodically fetch data from API Service A and setDataA(response)
    // ...periodically fetch data from API Service B and setDataB(response)

    // get a copy of the commonKey array
    const newArr = [...commonKey];
    // sort the keys using differece of two consecutive diffs
    newArr.sort((p, q) => dataA[p] - dataB[p] - (dataA[q] - dataB[q]));
    // set the sorted array to state
    setCommonKey(newArr);
  }, []);

为避免滚动问题,请保存 scrollY 位置并在 useLayoutEffect 内更新 commonKey 后滚动到该位置。

 useEffect(() => {
    const updatePosition = () => {
      setCurrentScrollY(window.scrollY);
    };
    window.addEventListener("scroll", updatePosition);
    updatePosition();
    return () => window.removeEventListener("scroll", updatePosition);
  }, []);

  useLayoutEffect(() => {
    window.scrollTo(0, currentScrollY);
  }, [commonKey]);