簡體   English   中英

添加 object 值以使用 React 的備忘錄掛鈎

[英]Adding object values to useMemo hook for React

我正在嘗試使用從數據庫中提取的數據創建一個反應表組件。 從我閱讀的文檔( https://react-table.tanstack.com/docs/quick-start )來看,react-table 庫似乎使用 useMemo 掛鈎來創建將顯示在表格上的數據。 但是,我實際上在將數據添加到 useMemo 掛鈎時遇到了麻煩,因為我不熟悉它。

我有一個簡單的 JS object,它保存了我們數據庫中發生的每種中斷類別的實例計數。 獲得計數后,我會嘗試將其傳遞給我的 useMemo 實例,但是會返回未定義的“streamCount”的屬性。 我想我錯誤地將 object 傳遞給 useMemo。 任何幫助表示贊賞。

function Leaderboard(props){
    const data = props.tableData;
    console.log(data); //this is the data that is pulled from our DB and is passed as a prop into the component
    
    let counts = {
      streamCount: 0,
      powerCount: 0,
      internetCount: 0,
      gamingPlatformCount: 0,
      cableCount: 0,
      websiteCount: 0,
    } //the object that holds the number of instances each category occurs in our data

    for(var i = 0; i < data.length; i++){ //checks the data and updates the counts for each category
      switch(data[i].service_type) {
        case "Streaming":
          counts.streamCount += 1;
          break;
        case "Power":
          counts.powerCount+= 1;
          break;
        case "Internet":
          counts.internetCount+= 1;
          break;
        case "Gaming Platform":
          counts.gamingPlatformCount += 1;
          break;
        case "Cable":
          counts.cableCount += 1;
          break;
        case "Website":
          counts.websiteCount += 1;
          break;
        default:
          break;
      }
    }

    console.log(counts) //This returns the correct values of each count when line 41-69 is commented, but returns 0 for all values when those lines are uncommented.

    let outageCounts = React.useMemo(
      (counts) => [
        {
          type: 'Streaming',
          count: counts.streamCount,
        },
        {
          type: 'Power',
          count: counts.powerCount,
        },
        {
          type: 'Internet',
          count: counts.internetCount,
        },
        {
          type: 'GamingPlatform',
          count: counts.gamingPlatformCount,
        },
        {
          type: 'Cable',
          count: counts.cableCount,
        },
        {
          type: 'Website',
          count: counts.websiteCount,
        },
      ],
      []
    );
    
    //this will be updated to have the accessor be 'count' from outageCounts instead of 'service_type' from data when the bug is resolved. For now it is just using data to test to see if the table would render at all.
    const columns = React.useMemo(
        () => [
          {
            Header: 'Service Type',
            accessor: 'service_type',
          },
        ],
        []
    );
    
    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow,
    } = useTable({ columns, data}) //data will eventually be changed to outageCounts
    
    return (
        <table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
          <thead>
            {headerGroups.map(headerGroup => (
              <tr {...headerGroup.getHeaderGroupProps()}>
                {headerGroup.headers.map(column => (
                  <th
                    {...column.getHeaderProps()}
                    style={{
                      borderBottom: 'solid 3px red',
                      background: 'aliceblue',
                      color: 'black',
                      fontWeight: 'bold',
                    }}
                  >
                    {column.render('Header')}
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody {...getTableBodyProps()}>
            {rows.map(row => {
              prepareRow(row)
              return (
                <tr {...row.getRowProps()}>
                  {row.cells.map(cell => {
                    return (
                      <td
                        {...cell.getCellProps()}
                        style={{
                          padding: '10px',
                          border: 'solid 1px gray',
                          background: 'papayawhip',
                        }}
                      >
                        {cell.render('Cell')}
                      </td>
                    )
                  })}
                </tr>
              )
            })}
          </tbody>
        </table>
    );
  }
export default Leaderboard;

useMemo鈎子的回調 function 不需要任何 arguments,它只需要一個回調 function,它返回一個您想要或需要的值和一個依賴數組來記憶。

使用備忘錄

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

返回一個記憶值。

傳遞一個“創建” function 和一個依賴數組。 useMemo只會在依賴項之一發生更改時重新計算記憶值。 這種優化有助於避免在每次渲染時進行昂貴的計算。

將計算計數的邏輯移到useMemo回調中,並使用data (props 值)作為依賴項。 您可以通過抽象將service_type映射到counts鍵之一然后映射回來但僅使用service_type作為counts鍵的通用模式來簡化/減少代碼以更加 DRY。 通過此更改,您可以簡單地使用動態 object 屬性來更新每種中斷類型的計數。 計算完計數后,創建一個鍵值對數組,從 object 和 map 到具有typecount鍵的對象數組。

const outageCounts = React.useMemo(() => {
  const counts = {
    Streaming: 0,
    Power: 0,
    Internet: 0,
    "Gaming Platform": 0,
    Cable: 0,
    Website: 0
  };

  data.forEach(({ service_type }) => {
    if (Object.hasOwnProperty.call(counts, service_type)) {
      counts[service_type] += 1;
    }
  });

  return Object.entries(counts).map(([type, count]) => ({ type, count }));
}, [data]);

 function App({ data = [] }) { const outageCounts = React.useMemo(() => { const counts = { Streaming: 0, Power: 0, Internet: 0, "Gaming Platform": 0, Cable: 0, Website: 0 }; data.forEach(({ service_type }) => { if (Object.hasOwnProperty.call(counts, service_type)) { counts[service_type] += 1; } }); return Object.entries(counts).map(([type, count]) => ({ type, count })); }, [data]); //console.log({ outageCounts }); return ( <div className="App"> <h1>Outage Counts</h1> <ul> {outageCounts.map(({ type, count}) => ( <li key={type}> {type}: {count} </li> ))} </ul> </div> ); } const service_types = [ "Streaming", "Power", "Internet", "Gaming Platform", "Cable", "Website" ]; // Generate "random" outage data const data = Array.from({ length: Math.floor(Math.random() * 1000) }, () => ({ service_type: service_types[Math.floor(Math.random() * service_types.length)] })); const rootElement = document.getElementById("root"); ReactDOM.render( <App data={data} />, rootElement );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script> <div id="root" />

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM