于是我开始学习使用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;
所以我遇到了一些 "设计问题"。
const
但是数据存储在哪里呢?(我通常会把它存储在一个类中,但由于我试图使用钩子,我不确定)useEffect()
是错误的,用于获取API数据。我还遇到了一个bug,它不断地运行。我看到有人建议检查长度来防止这种情况......但这感觉很黑。正确的方法是什么呢?React.useMemo
我也找不到任何例子(显然反应表需要这样)。有什么建议吗?我只是真的不知道如何正确设置。我似乎也找不到人们使用react table with json api fetching的例子。
你的代码是好的,除了一些修改。你可以找到最终的代码 此处
HowWhere do people normally setstore the column data and "data" data when using react table. 我假设只是一个 const
但是数据存储在哪里呢?(我通常会把它存储在一个类中,但由于我试图使用钩子,我不确定)
答案
我觉得我的 useEffect()
是错误的,用于获取API数据。我还遇到了一个bug,它不断地运行。我看到有人建议检查长度来防止这种情况......但这感觉很黑。请问正确的方法是什么?
答:
[]
)作为第二个参数。所以它从来没有重新运行过。我不太明白如何用以下方法来映射数据 React.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
在工作中添加了最终代码 代码和盒子在这里