reactjs 未使用处理程序属性和自定义排序方法更新父级状态的React子级

3z6pesqy  于 2023-03-08  发布在  React
关注(0)|答案(1)|浏览(91)

我有下面的父组件,它使用dynamicSort,一个对象数组的自定义排序函数,它返回一个按指定键排序的对象数组,我已经确认排序函数可以工作:

import React, { useState, useEffect } from 'react';
import { dynamicSort } from '../helpers';
import Container, ChildHeader, Childbody, Spinner, etc...

const Parent = () => {
  const [listItems, setListItems] = useState([]);

  useEffect(() => {
    // fetch list items and set them here on component mount
    // this works currently
  }, [])

  const sortList = column => {
    setListItems(prev => dynamicSort(prev, column, 'asc'));
  };

  return (
    <Container>
        <ChildHeader
          sortList={sortList}
        />
        <ChildBody>
          {listItems !== [] ? (
            listItems.map(item => {
              return (
                <ChildRow
                  key={item.id}
                  rowItem={item}
                />)
            })
          ) : (
            <Spinner />
          )}
        </ChildBody>
    </Container>
  );
};

export default Parent;

在childHeader中,我在标题单击时调用prop sortList,如下所示:

const ChildHeader = ({ sortList }) => {
    return (
      <HeaderContainer>
        <Column1
          onClick={() => {
            sortList('Column1'); // This should sort and reset the state of the list in the parent
          }}
        >
          {'Column Label'}
        </Column1>
        // More columns...
      </HeaderContainer>
    );
};

export default ChildHeader;

我已经确认了当点击子组件时会调用这个处理程序,但是由于某种原因,父列表的状态没有更新,更奇怪的是,如果我把父列表中的sortList方法改为下面的代码,那么子组件点击时列表会更新。

const sortList = column => {
    setListItems(prev => prev.slice(0, 3); // Using slice instead of my custom sort method
};

这让我觉得我的sort方法有问题。我已经确认sort方法确实返回了一个对象数组,并且排序正确。有人知道发生了什么吗?我将在下面添加sort方法,只是为了好玩:

export const dynamicSort = (list, column, direction) => {
  const compare = (a, b) => {
    switch (column) {
      case 'Column1':
        if (direction === 'asc') {
          if (a.key1 > b.key1) {
            return 1;
          }
          if (a.key1 < b.key1) {
            return -1;
          }
          return 0;
        }
        if (direction === 'desc') {
          if (a.key1 < b.key1) {
            return 1;
          }
          if (a.key1 > b.key1) {
            return -1;
          }
          return 0;
        }
      // More cases following below

      default:
        return null;
    }
  };
  return list.sort(compare); // This does return an array of objects sorted correctly by key 
}
ozxc1zmp

ozxc1zmp1#

因为你不是在更新状态,而是在改变状态,根据the documentation for sort
sort()方法对数组的元素进行排序(in place),并返回对已排序的同一数组的引用。
因此,您将状态更新为 * 相同的数组引用 *,这意味着React无法知道状态已被以任何方式修改。
最简单的方法可能是修改dynamicSort函数来排序一个新的数组引用,这可能就像在排序之前先对数组进行解构一样简单:

return [...list].sort(compare);

相关问题