React Table wJSON API挂钩?

问题描述 投票:0回答:1

于是我开始学习使用React Table(https:/github.comtannerlinsleyreact-table。)它是相当精巧的。然而,我是React的中级水平(我了解基本的lifeecycleprops等),但钩子对我来说相当陌生。

我决定在一个主要是类的个人项目中使用它。它调用一个API(我在Rails中写的)来返回一些基本的JSON信息。我使用axios (https:/github.comaxiosaxios。)来调用API。

从学习react钩子开始,我就把原来我的 componentDidMount() 召见 useEffect() 的调用。下面是Table和Table Container的代码(它是为处理传感器的应用而设计的,所以名字也是这样)

传感器容器。

import React, { useState, useEffect } from "react";
import axios from "axios";
import SensorCard from "./SensorCard";
import SensorTable from "./SensorTable";
import "../Styles/Components/_SensorContainer.css";

function SensorContainer() {
  const [sensors, setSensors] = useState([]);
  const [data, setData] = useState([])

  useEffect(() => {
    // GET sensor list from API
    axios
    .get("http://localhost:3000/api/v1/devices.json")
    .then((response) => {
      // handle success
      console.log(response);
      setSensors(response.data.data)
    })
    .then(() => {
      console.log(sensors)
      console.log(sensors[0].attributes)
      console.log(name)
      console.log(serialNumber)
      console.log(deviceStatus)
      const { name, 'serial-number':serialNumber, 'device-status':deviceStatus} = sensors[0].attributes
      const data = sensors.map(sensor => 
        ({ 
          id: sensor.id, 
          name: name, 
          serialNum: serialNumber,
          status: deviceStatus
        })
      )
    setData(data)
    })
    .catch((error) => {
      console.log(error);
    })
  }, [sensors.length]);





  // const data = React.useMemo(
  //   () => [
  //     {
  //       id: '1',
  //       name: 'TEMP001',
  //       serialNum: 'Temp Sensor',
  //       status: 'Active',
  //     },
  //     {
  //       id: '2',
  //       name: 'TEMP002',
  //       serialNum: 'Temp Sensor',
  //       status: 'Unknown',
  //     },
  //     {
  //       id: '3',
  //       name: 'HUM001',
  //       serialNum: 'Humidity Sensor',
  //       status: 'Active',
  //     },
  //   ],
  //   []
  // )

  const columns = React.useMemo(
    () => [
      {
        Header: 'ID',
        accessor: 'id', // accessor is the "key" in the data
      },
      {
        Header: 'Name',
        accessor: 'name',
      },
      {
        Header: 'Serial Number',
        accessor: 'serialNum',
      },
      {
        Header: 'Status',
        accessor: 'status',
      },
    ],
    []
  )
  return (
    <div>
      <SensorTable columns={columns} data={data} />
    </div>
  )
}

export default SensorContainer;

Sensor Table:

import React from "react";
import {
  useTable,
  useGroupBy,
  useFilters,
  useSortBy,
  useExpanded,
  usePagination,
} from "react-table";
import "../Styles/Components/_SensorTable.css";

function SensorTable({ columns, data }) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
  } = useTable({ columns, data })

  // Render the UI for your table
  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 SensorTable;

所以我遇到了一些 "设计问题"。

  1. 当使用react表时,人们通常在哪里设置存储列数据和 "数据 "数据?我假设只是一个 const 但是数据存储在哪里呢?(我通常会把它存储在一个类中,但由于我试图使用钩子,我不确定)
  2. 我觉得我的 useEffect() 是错误的,用于获取API数据。我还遇到了一个bug,它不断地运行。我看到有人建议检查长度来防止这种情况......但这感觉很黑。正确的方法是什么呢?
  3. 我不太明白怎么用数据映射我想用的方式。React.useMemo 我也找不到任何例子(显然反应表需要这样)。有什么建议吗?

我只是真的不知道如何正确设置。我似乎也找不到人们使用react table with json api fetching的例子。

reactjs axios react-table
1个回答
1
投票

你的代码是好的,除了一些修改。你可以找到最终的代码 此处

  1. HowWhere do people normally setstore the column data and "data" data when using react table. 我假设只是一个 const 但是数据存储在哪里呢?(我通常会把它存储在一个类中,但由于我试图使用钩子,我不确定)

    答案

    • 它是基于应用需求的。
    • 如果数据需要在客户端持久化,并在几个模块组件之间共享,那么使用 再版 来存储您的数据。
    • 如果只在用户访问屏幕时才需要数据(不需要长期保存),则将数据保存在 部件状态.
  2. 我觉得我的 useEffect() 是错误的,用于获取API数据。我还遇到了一个bug,它不断地运行。我看到有人建议检查长度来防止这种情况......但这感觉很黑。请问正确的方法是什么?

    :

    • 根据你的代码,不需要在你的代码中传递依赖关系。使用效果 钩子。(发生这种情况是因为你正试图在两个组件状态下维护相同的数据,也就是 数据的传感器.但没有必要--PS请看上面链接中的附件代码。有一个看 条件性过滤效果
    • 如果你想在挂载时只运行一次效果(componentDidMount),你可以传递一个空数组([])作为第二个参数。所以它从来没有重新运行过。
  3. 我不太明白如何用以下方法来映射数据 React.useMemo 我也找不到任何例子(显然反应表需要这样)。有什么建议吗?

    回答:

    • 你说的是什么意思?如何映射数据?. 想从API的响应对象上做一些转换?如果是,你可以使用任何Javascript内置的方法,或者你可以使用第三方的库,如。夯实宿雾
    • 使用备忘录 在你的情况下是不需要的,因为你没有做任何复杂的操作,你的数据源是API。
    • 在reactjs文档中提到的一些注意事项是关于 useMemo钩子

记住,传递给useMemo的函数在渲染过程中运行。 不要在那里做任何你通常不会在渲染时做的事情。 例如,副作用属于useEffect,而不是useMemo。

你的代码很好,除了在两个独立的组件状态变量中维护相同的数据外,没有任何问题。

请参考标有 <---- 在下面的代码中

  // const [sensors, setSensors] = useState([]); No need to maintain same data in two state variables
  const [data, setData] = useState([])

  useEffect(() => {
    // GET sensor list from API
    axios
    .get("http://localhost:3000/api/v1/devices.json")
    // .then((response) => {  
    //  handle success
    //  console.log(response);
    //  setSensors(response.data.data)
    // }) <------- this is not required
    .then((response) => {
      // ......
      const data = response.data.data.map(sensor => 
        ({ 
          id: sensor.id, 
          name: sensor.name, 
          serialNum: sensor.serialNumber,
          status: sensor.deviceStatus
        })
      )
      setData(data)
    })
    .catch((error) => {
      console.log(error);
    })
//  }, [sensors.length]);
}, []); // <--------- like componentDidMount in classBased components 

在工作中添加了最终代码 代码和盒子在这里

© www.soinside.com 2019 - 2024. All rights reserved.