【问题标题】:Adding object values to useMemo hook for React为 React 添加对象值到 useMemo 钩子
【发布时间】:2022-01-15 14:35:16
【问题描述】:

我正在尝试使用从数据库中提取的数据创建一个反应表组件。从我读过的文档(https://react-table.tanstack.com/docs/quick-start)来看,react-table 库似乎使用 useMemo 挂钩来创建将显示在表格上的数据。但是,我在向 useMemo 钩子添加数据时遇到了麻烦,因为我不熟悉它。

我有一个简单的 JS 对象,它保存在我们的数据库中发生的每种中断类别的实例计数。获得计数后,我会尝试将其传递给我的 useMemo 实例,但是会返回未定义的“streamCount”的属性。我想我将对象传递给 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;

【问题讨论】:

    标签: javascript reactjs react-hooks javascript-objects react-usememo


    【解决方案1】:

    useMemo 钩子的回调函数不接受任何参数,它只接受一个回调函数,该函数返回一个您想要或需要记忆的值和一个依赖数组。

    useMemo

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

    返回一个记忆值。

    传递一个“create”函数和一个依赖数组。 useMemo会 仅当依赖项之一具有时才重新计算记忆值 改变了。这种优化有助于避免昂贵的计算 每次渲染。

    将计算计数的逻辑移到useMemo 回调中,并使用data(props 值)作为依赖项。您可以通过抽象将service_type 映射到counts 键之一然后映射回来但仅使用service_type as counts 键。通过此更改,您可以简单地使用动态对象属性来更新每种中断类型的计数。计算完计数后,从对象创建一个键值对数组,并将其映射到具有 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" />

    【讨论】:

      猜你喜欢
      • 2019-08-20
      • 2021-06-19
      • 1970-01-01
      • 2022-08-16
      • 2022-01-01
      • 2020-01-14
      • 2021-11-10
      • 1970-01-01
      • 2019-05-11
      相关资源
      最近更新 更多