まず結論から話しましょう
useEffect が依存関係を挿入した後、状態データに最新の値を出力させるのはクロージャですが、onTableChange イベントに出力されるのは、クロージャが取得されたときにキャッシュされた値です。
解決
useRef
状態を保存するために導入されたこれにより、取得されるすべての参照が新しく一意の最新値になることが保証されます。
コード例:
// 编码模块
const Code = (props) => {
const {
searchParams, setSearchParams, selectedRowKeys, setSelectedRowKeys, tenantCode } = props;
// 创建newSearchParamsRef的目的是为了避免闭包导致影响获取最新数据,闭包会缓存上一次的数据
const newSearchParamsRef = useRef();
}
useLayoutEffect(() => {
codeFetchList(); // 更新table列表数据
newSearchParamsRef.current = {
...searchParams };
}, [searchParams, codeFetchList]);
// table onchange事件、排序
const handleTableChange = (pagination: any, filters: any, sorter: any) => {
const {
order, field } = sorter;
setSearchParams({
...(newSearchParamsRef.current || searchParams),
pageNo: 1,
});
};
<Table
sticky
rowKey={
(record: any) => record.id}
loading={
loading}
columns={
codeColumns}
dataSource={
codeList?.data?.rows}
onChange={
handleTableChange}
/>
)}
PS: 同様の質問 (元のリンク: https://blog.csdn.net/weixin_44634727/article/details/122666435):
antd のテーブル コンポーネントを使用して列をレンダリングする場合、親コンポーネントの状態を正しく取得できません。
問題の説明
まず、関数コンポーネントを使用しました(カプセル化のため、親コンポーネントの関数に次のコードを書きました)
次に、親コンポーネントで、特定の関数の ID を記録する状態を定義しました。
初期値は 333 (この 333 は後で役立ちます)
ですが、コンポーネントを表示するときに、 useEffect 関数を使用してバックエンドの最新の deptid を取得するリクエストを開始し、setDeptid を使用して deptid を再割り当てします。
deptid を再割り当てする前に、テーブルの列をレンダリングしました。
次の図は、列内の特定の操作列です。
上に示すように、削除ボタンは deleteItem 関数です。
図に示すように、関数を実行すると親コンポーネントの状態が出力されますが、出力は 1 であり、最新のデータではありません。
原因分析
究其原因发现原来,是我掉进了闭包陷阱当中
テーブルをレンダリングするときに、前の deptid を deleteItem に入れて、前の 333 をメモリにキャッシュするクロージャを形成しました。その後、ボタンをもう一度クリックして deleteItem 関数をトリガーすると、値が再びキャッシュから取り出されます。表示されているのは以前の値であり、クラスコンポーネントにはこの問題は存在しません。
解決
上の図に示すように、解決策は親コンポーネントで useRef フックを使用して最新のデータを保存することです (必要な場合は console.log(countRef.current) だけを使用します)。