React.useMemo不更新数据
React.useMemo does not update the data
我是新手。所以这可能很简单,但我不知道如何解决:
我有一个这样的函数,它接受两个数组 columns
和 data
。并且这些数据应该被记住,否则它不起作用。 (由 react-table 人推荐)
function ReactTable(props) {
const columns = React.useMemo(() => props.columns, [])
const data = React.useMemo(() => props.data, [])
return <Table columns={columns} data={data} />
}
这很好用,但是当 props 发生变化时(比如在数据数组中添加或删除了一个项目),React.useMemo 不会将更新后的数据发送到 Table 组件。我该如何解决这个问题:(
这正是 hooks 中依赖数组的用途。您可以定义 'trigger' 钩子上的变化的变量。在您的情况下,这意味着您需要将代码更改为以下内容:
function ReactTable(props) {
const columns = React.useMemo(() => props.columns, [props.columns]);
const data = React.useMemo(() => props.data, [props.data]);
return <Table columns={columns} data={data} />
}
这意味着,每当 props.columns
发生变化时,columns
变量都会更新,props.data
和 data
也是如此。
请注意,如果您使用的是 react-table 的排序挂钩 useSortBy
,则上述用户 Linschlager 的回答可能无法正常工作。事实上,作者最终的解决方案并没有涉及 react.useMemo
.
对我来说,无论如何都成功了。我的列和行数据来自一个查询数据对象,我必须解析它以适应 react-table 的特定方式。
看起来像这样:
function ReportTable({ queryData }) {
... other data such as {selectedPerLevel} ...
/* COLUMNS */
let firstColumn = {
Header: ' ',
columns: [
{
Header: selectedPerLevel.name,
accessor: 'perLevel',
},
],
};
let otherColumns = [];
queryData.weeks.forEach((week) => {
let otherColumn = {
Header: week,
Footer: ' ',
center: true,
columns: [
{
Header: 'Ratio',
accessor: `ratio${week}`,
},
{
Header: 'Count',
accessor: 'count' + week,
},
],
};
otherColumns = [...otherColumns, otherColumn];
});
/* ROWS */
let listOfRows = queryData.units.map((unit) => {
let row = {};
// for each column
unit.items.forEach(({ week, ratio, count}) => {
row = {
...row,
['ratio' + week]: ratio,
['count' + week]: count,
};
});
// add the first column-data to the row
row = { ...row, perLevel: unit.name, id: unit.id };
return row;
});
const data = React.useMemo(() => listOfRows, [queryData]);
const columns = React.useMemo(() => [{ ...firstColumn }, ...otherColumns], [queryData]);
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable({data, columns}, useSortBy);
return <Table ....
我不知道这是否对任何人有帮助,但使用上述解决方案对我来说一切都很好。
我是新手。所以这可能很简单,但我不知道如何解决:
我有一个这样的函数,它接受两个数组 columns
和 data
。并且这些数据应该被记住,否则它不起作用。 (由 react-table 人推荐)
function ReactTable(props) {
const columns = React.useMemo(() => props.columns, [])
const data = React.useMemo(() => props.data, [])
return <Table columns={columns} data={data} />
}
这很好用,但是当 props 发生变化时(比如在数据数组中添加或删除了一个项目),React.useMemo 不会将更新后的数据发送到 Table 组件。我该如何解决这个问题:(
这正是 hooks 中依赖数组的用途。您可以定义 'trigger' 钩子上的变化的变量。在您的情况下,这意味着您需要将代码更改为以下内容:
function ReactTable(props) {
const columns = React.useMemo(() => props.columns, [props.columns]);
const data = React.useMemo(() => props.data, [props.data]);
return <Table columns={columns} data={data} />
}
这意味着,每当 props.columns
发生变化时,columns
变量都会更新,props.data
和 data
也是如此。
请注意,如果您使用的是 react-table 的排序挂钩 useSortBy
,则上述用户 Linschlager 的回答可能无法正常工作。事实上,作者最终的解决方案并没有涉及 react.useMemo
.
对我来说,无论如何都成功了。我的列和行数据来自一个查询数据对象,我必须解析它以适应 react-table 的特定方式。
看起来像这样:
function ReportTable({ queryData }) {
... other data such as {selectedPerLevel} ...
/* COLUMNS */
let firstColumn = {
Header: ' ',
columns: [
{
Header: selectedPerLevel.name,
accessor: 'perLevel',
},
],
};
let otherColumns = [];
queryData.weeks.forEach((week) => {
let otherColumn = {
Header: week,
Footer: ' ',
center: true,
columns: [
{
Header: 'Ratio',
accessor: `ratio${week}`,
},
{
Header: 'Count',
accessor: 'count' + week,
},
],
};
otherColumns = [...otherColumns, otherColumn];
});
/* ROWS */
let listOfRows = queryData.units.map((unit) => {
let row = {};
// for each column
unit.items.forEach(({ week, ratio, count}) => {
row = {
...row,
['ratio' + week]: ratio,
['count' + week]: count,
};
});
// add the first column-data to the row
row = { ...row, perLevel: unit.name, id: unit.id };
return row;
});
const data = React.useMemo(() => listOfRows, [queryData]);
const columns = React.useMemo(() => [{ ...firstColumn }, ...otherColumns], [queryData]);
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable({data, columns}, useSortBy);
return <Table ....
我不知道这是否对任何人有帮助,但使用上述解决方案对我来说一切都很好。