reactjs - 通过过滤每个 JSON 对象创建可定制的反应表
问题描述
我是新手,我需要有关如何执行以下操作的帮助。我想创建一个包含 5 列的表,其中每列标题代表时间 1pm、2pm、3pm、4pm、5pm 和 7 行代表周日至周六的日子。
后端将返回以下 JSON 数组
例子:
[{"day": "Sunday", "Time": "2pm", "activity": "Golf"}
{"day": "Sunday", "Time": "3pm", "activity": "Football"}
{"day": "Sunday", "Time": "2pm", "activity": "Basketball"}
{"day": "Monday", "Time": "2pm", "activity": "Sleep"}]
我想检查日期和时间并在相应的表格单元格中写入活动。
示例: 第一个 JSON 对象,活动“GOLF”应写入表格单元格 [Sunday,2pm]。注意:我可以将 2 个活动映射到同一个单元格
-------------------------------------------------------------------
| | 1pm | 2pm | 3pm | [...] |
| Sunday | | GOLF | Football | |
BasketBall
| Monday | | Sleep | | |
| Tuesday | | | | |
| Wednesday | | | | |
| Thursday | | | | |
| Friday | | | | |
| Saturday | | | | |
--------------------------------------------------------------------
正如我上面提到的,我仍然是 React 的新手,所以任何能帮助我了解 React 中的表格以及如何实现上述功能的资源的帮助将不胜感激。我尝试阅读 useTable Hooks 但对每个内容感到不知所措
{getTableProps,getTableBodyProps,headerGroups,rows,prepareRow}
意思以及我如何使用它们来执行我想要的。
我尝试实施的内容:
import React, {useMemo} from 'react'
import {useTable} from 'react-table'
import {COLUMNS} from './Columns'
import MOCK_DATA from './ActivityMOCK.json'
import './table.css'
export const Table= ()=> {
const columns = useMemo(()=> COLUMNS, [])
const data = useMemo(()=> MOCK_DATA,[])
const tableInstance = useTable({
columns,
data
})
const {getTableProps,getTableBodyProps,headerGroups,rows,prepareRow} = tableInstance
return (
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>{column.render('Header')}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
})}
</tr>
)
})}
</tbody>
</table>
)
}
列.js
export const COLUMNS =[
{
Header: 'Day',accessor: 'day'
},
{
Header: '1pm', accessor: '1pm'
},
{
Header: '2pm', accessor: '2pm'
},
{
Header: '3pm',accessor: '3pm'
},
{
Header: '4pm',accessor: '4pm'
},
{
Header: '5pm',accessor: '5pm'
}
]
输出:
----------------------------------------------------------
| | 1pm | 2pm | 3pm | [...] |
| Sunday | | | | |
| Sunday | | | | |
| Sunday | | | | |
| Monday | | | | |
--------------------------------------------------------------------
我不希望每天都这样重复,我想在正确的单元格中添加映射到相应日期/时间的整个 JSON 对象,但我似乎无法弄清楚该方法。我什至应该使用表吗?
解决方案
首先,我们需要确保以您可以使用的表格格式正确获取数据。我认为你展示的结构缺乏目的,有一个日期会比一个工作日有用得多,但是我在这里使用它,因为它是你数据的一部分
const dataSet = [{"day": "Sunday", "Time": "2pm", "activity": "Golf"},
{"day": "Sunday", "Time": "3pm", "activity": "Football"},
{"day": "Sunday", "Time": "2pm", "activity": "Basketball"},
{"day": "Monday", "Time": "2pm", "activity": "Sleep"}];
const weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
// map all the data you need together
const groupedData = dataSet.reduce( (agg, cur) => {
// this assumes the day always exists, isn't written differently
// you may need to proof that a bit better in your real code
const target = agg[cur.day];
if (target[cur.Time]) {
target[cur.Time].push( cur.activity );
} else {
target[cur.Time] = [cur.activity];
}
return agg;
}, Object.assign( {}, ...weekdays.map( day => ({[day]: {}}) ) ) );
// based on that grouping, extract the keys and make it part of the column data
// time has now become a column, and activity will be an array inside that column
const tableData = Object.keys( groupedData ).map( day => ({ day, ...groupedData[day] }) );
然后tableData
,您可以将其用作表实例本身的一部分,但是,您可能必须更改活动数组的呈现方式。
然而,这现在确实意味着,您需要更新列中的内容(我将在后续编辑中尝试提供一个完整的示例):
const CellRenderer = ( { value } ) => {
if (!value || !Array.isArray( value ) ) {
return null;
}
return (
<React.Fragment>
{ value.map( v => <div>{ v }</div> ) }
</React.Fragment>
);
};
}
export const COLUMNS =[
{
accessor: 'day'
},
{
Header: '1pm', accessor: '1pm', Cell: CellRenderer
},
{
Header: '2pm', accessor: '2pm', Cell: CellRenderer
},
{
Header: '3pm',accessor: '3pm', Cell: CellRenderer
},
{
Header: '4pm',accessor: '4pm', Cell: CellRenderer
},
{
Header: '5pm',accessor: '5pm', Cell: CellRenderer
}
]
const { useMemo } = React;
const { useTable } = ReactTable;
window.process = { cwd: () => '' };
// the component, pass columns & data as properties
const Table = ( { columnSet, dataSet } ) => {
const data = useMemo( () => {
const weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
// map all the data you need together
const groupedData = dataSet.reduce( (agg, cur) => {
// this assumes the day always exists, isn't written differently
// you may need to proof that a bit better in your real code
const target = agg[cur.day];
if (target[cur.Time]) {
target[cur.Time].push( cur.activity );
} else {
target[cur.Time] = [cur.activity];
}
return agg;
}, Object.assign( {}, ...weekdays.map( day => ({[day]: {}}) ) ) );
// based on that grouping, extract the keys and make it part of the column data
// time has now become a column, and activity will be an array inside that column
const tableData = Object.keys( groupedData ).map( day => ({ day, ...groupedData[day] }) );
return tableData;
}, [ dataSet ] );
const columns = useMemo( () => columnSet, [columnSet] );
const tableInstance = useTable({
columns,
data
});
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow
} = tableInstance;
return (
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>{column.render('Header')}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
})}
</tr>
)
})}
</tbody>
</table>
)
}
// the columns and cell rendering
const CellRenderer = ( { value } ) => {
if (!value || !Array.isArray( value ) ) {
return null;
}
return (
<React.Fragment>
{ value.map( v => <div key={v}>{ v }</div> ) }
</React.Fragment>
);
};
const columns = [
{
accessor: 'day'
},
{
Header: '1pm', accessor: '1pm', Cell: CellRenderer
},
{
Header: '2pm', accessor: '2pm', Cell: CellRenderer
},
{
Header: '3pm',accessor: '3pm', Cell: CellRenderer
},
{
Header: '4pm',accessor: '4pm', Cell: CellRenderer
},
{
Header: '5pm',accessor: '5pm', Cell: CellRenderer
}
]
// the data to be used
const dataSet = [{"day": "Sunday", "Time": "2pm", "activity": "Golf"},
{"day": "Sunday", "Time": "3pm", "activity": "Football"},
{"day": "Sunday", "Time": "2pm", "activity": "Basketball"},
{"day": "Monday", "Time": "2pm", "activity": "Sleep"}];
const target = document.getElementById('container');
ReactDOM.render( <Table
columnSet={ columns }
dataSet={ dataSet } />, target );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.development.js" integrity="sha512-uDcVu1L9rOVnYAEDiN49qYQuVQeqCNQw7lbiqF8gTNqmFaQw0NFBiFrbGkpbKkIH1HjJpKI7wgvE7tLpSWpMqQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha512-0uQJWYKqppuntnX/9xmazR1YADGh7MAficuBoyioWv37RUVN/ueAeXibDK+acJsa1AjkOtQXc3gO9j/Q3QRxjA==" crossorigin="anonymous"></script>
<script src="https://unpkg.com/react-table@7.6.2/dist/react-table.development.js"></script>
<div id="container"></div>
推荐阅读
- javascript - react native如何从php获取json
- events - 如何在wix中使用mixpanel与某种事件
- mysql - MySQL死锁使用具有新值的索引
- javascript - 根据数组值加扰字符串 - Javascript
- xml - 是否可以将属性的值放入数组中?
- java - 创建新的 XSSFWorkbook .xlsx 文件时出错?
- python - 获取“关键错误:var_cheeze_value11”
- python - 文字冒险游戏没有产生正确的输出
- python - AWS boto3:看到客户端正在使用传输加速端点的证据?
- javascript - 如何使用 React 在标签中设置 img?