如果完成初始排序,则使用排序数组的 React useState 不会导致语义 UI 表的重新呈现



我有一个带有SemanticUI的表,它呈现了公司列表,并允许根据单击表的标题来重新调整列表。 我以为我已经完成了这个工作(dev env 向我发送了一个预先排序的列表(,但在编写测试时,我意识到我不能保证列表是预先排序的。
所以我编辑了我的初始useState逻辑,使其具有与标题单击相同的排序函数:

之前(作品(:const [data, setData] = useState(companies);

之后(不起作用(:const [data, setData] = useState(companySortData(companies, COLUMN_NAME.NAME));

上述两个初始 UI 看起来都没问题,但是当我单击标题时,这就是问题出现的地方:UI 不会更改(重新渲染(。

在我逐步完成代码时,我看到正确的重新排序数组在那里,但在 React 内部的某个地方,数组不会触发状态更改。

我尝试了大量的选择,包括:1(更改状态,使data成为sortedColumnData的一部分,2(制作一个useEffect钩,允许初始公司数据在那里,然后我们setData。 3( 尝试创建一个比较sortedColumnDatausePrevious钩子,然后在该依赖项更改时调用setData。 4(从功能组件更改为纯组件,但这也不能完全解决它。

我知道 React 只有浅层差异,所以这可能是它的一部分,但数据数组形状本身很浅,所以我认为这会被拾取(如果我不对数据进行初始排序,就会这样做(:

{
id: "newnew",
name: "A New New Company",
subdomain: "newnew",
createdAt: "2019-10-28T21:54:30.253Z",
updatedAt: "2019-10-28T21:54:30.253Z"
},

所以,这里有一个CodeSandBox链接:https://codesandbox.io/s/wonderful-thompson-vg2x1

下面是组件本身:

export const CompanyTable = ({ companies }) => {
const [sortedColumnData, setSortedColumnData] = useState({
data: companySortData(companies, COLUMN_NAME.NAME), // swap this initial sorting with just the `companies` and this table works fine
direction: DIRECTION.ASCENDING,
columnName: COLUMN_NAME.NAME
});
const handleClick = clickedColumn => {
if (!clickedColumn) return;
if (sortedColumnData.columnName !== clickedColumn) {
setSortedColumnData({
data: companySortData(sortedColumnData.data, clickedColumn),
columnName: clickedColumn,
direction: DIRECTION.ASCENDING
});
return;
}
setSortedColumnData({
data: sortedColumnData.data.reverse(),
columnName: clickedColumn,
direction:
sortedColumnData.direction === DIRECTION.ASCENDING
? DIRECTION.DESCENDING
: DIRECTION.ASCENDING
});
};
return (
<Table celled selectable sortable>
<Table.Header>
<Table.Row>
{headerCells.map(cell => (
<Table.HeaderCell
key={`cell-${cell.testid}`}
sorted={
sortedColumnData.columnName === cell.clickHandlerText
? sortedColumnData.direction
: undefined
}
data-testid={`header-${cell.testid}`}
onClick={() => handleClick(cell.clickHandlerText)}
>
{cell.title}
</Table.HeaderCell>
))}
</Table.Row>
</Table.Header>
<Table.Body data-testid="company-table-body">
{sortedColumnData.data.map(
({ id, name, subdomain, createdAt, updatedAt }) => {
return (
<Table.Row
key={id}
role="link"
data-testid={id}
style={{ cursor: "pointer" }}
>
<Table.Cell singleLine>{name}</Table.Cell>
<Table.Cell singleLine>{subdomain}</Table.Cell>
<Table.Cell singleLine>{createdAt}</Table.Cell>
<Table.Cell singleLine>{updatedAt}</Table.Cell>
</Table.Row>
);
}
)}
</Table.Body>
</Table>
);
};

我不确定为什么使用重新排序的数组从设置状态重新渲染失败......

它的发生是因为您将 props 的引用传递给排序函数并尝试将其设置为状态,您不能改变 prop,这是 React 的基础。如果要将道具存储到状态中,请先杀死引用。希望它能回答你的疑问:)

const companySortData = (data, sortBy) => {
let copyData = JSON.parse(JSON.stringify(data));
return copyData.sort((a, b) => {
let x = a[sortBy];
let y = b[sortBy];
if (sortBy === COLUMN_NAME.CREATED || sortBy === COLUMN_NAME.UPDATED) {
x = new Date(a.createdAt);
y = new Date(b.createdAt);
} else {
x = a[sortBy].toLowerCase();
y = b[sortBy].toLowerCase();
}
return x < y ? -1 : x > y ? 1 : 0;
});
};

相关内容

  • 没有找到相关文章

最新更新