FluentUI DetailsList onColumnClick с перехватчиками React дает пустые элементы

Я пытаюсь создать DetailsList с сортируемыми столбцами (аналогично примеру в документации здесь: https://uifabric.azurewebsites.net/#/controls/web/detailslist), но вместо компонента класса я хочу использовать функциональные компоненты и хуки.

Проблема в том, что при выполнении функции onColumnClick массив «items» все еще пуст.

Это в основном настройка моего компонента:

const MyList= () => {
  const [items, setItems] = useState([]);
  const [columns, setColumns] = useState([]);

  useEffect(() => {
    const newItems = someFetchFunction()
    setItems(newItems);

    const newColumns= [
      {
        key: "column1",
        name: "Name",
        fieldName: "name",
        onColumnClick: handleColumnClick,
      },
      {
        key: "column2",
        name: "Age",
        fieldName: "age",
        onColumnClick: handleColumnClick,
      },
    ];
    setColumns(newColumns);
  }, []);

  const handleColumnClick = (ev, column) => {
    console.log(items); // This returns [] instead of a populated array.
  };

  return <DetailsList items={items} columns={columns} />;
};

Проблема в том, что в handleColumnClick items возвращает пустой массив. Это очевидная проблема, когда вы хотите отсортировать элементы по определенному столбцу.


comment
У меня та же проблема, у вас есть идея?   -  person Chris    schedule 28.10.2020


Ответы (1)


Я предполагаю, что массив элементов пуст, потому что состояние было украдено. Взгляните на эту статью: https://css-tricks.com/dealing-with-stale-props-and-states-in-reacts-financial-components/

Честно говоря, я не понимаю, почему это происходит, наверное, onColumnClick обрабатывается асинхронно ?!

Однако добавление хука useRef решает проблему для меня:

const MyList = () => {
  const [columns, setColumns] = useState([]);
  const [items, setItems] = useState([]);
  const refItems = useRef(items);

  const updateItems = (newItems) => {
    refItems.current = newItems;
    setItems(newItems);
  }

  useEffect(() => {
    const newItems = someFetchFunction()
    updateItems(newItems);

    const newColumns = // ...
    setColumns(newColumns);
  }, []);

  const handleColumnClick = (ev, column) => {
    console.log(refItems.current);
  };

  return <DetailsList items={items} columns={columns} />;
};
person Chris    schedule 28.10.2020