Управление состоянием кнопок и обработка результатов с помощью React Hooks - PullRequest
0 голосов
/ 13 января 2020

У меня есть несколько переключателей, которые можно включать / выключать. Они получают состояние включения / выключения от родительского функционального компонента. Когда пользователь переключает состояние, мне нужно обновить состояние в родительском элементе и запустить функцию.

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

В настоящее время они переключаются очень хорошо, но рендер не синхронизируется c с состоянием кнопок, потому что функция обработки заканчивает чтение в старом состоянии.

Я пытался использовать useEffect (), но поскольку у функции много зависимостей, это вызывает al oop.

Я попытался связать useRef () с useState () в пользовательском хуке, чтобы прочитать текущее состояние, по крайней мере, самой новой группы фильтров, которая была установлена, но там тоже не повезло.

Есть какие-нибудь предложения о том, как мне вообще лучше реструктурировать свой код, или потенциальное решение этой текущей проблемы?

Функция брутто, которая выполняет фильтрацию:

function filterItems(threshold, items = {}) {
    const { values } = kCoreResult;
    const { coloredItems } = rgRef.current;

    let itemsForUse;
    let filteredItems;

    if (Object.entries(items).length === 0 && items.constructor === Object) {
      itemsForUse = baseItemsRef.current;
    } else {
      itemsForUse = items;
    }

    const isWithinThreshold = id => has(values, id) && values[id] >= threshold;

    // filter for nodes meeting the kCoreValue criterion plus all links
    filteredItems = pickBy(
      itemsForUse,
      (item, id) => !isNode(item) || isWithinThreshold(id)
    );
    filteredItems = pickBy(
      filteredItems,
      item =>
        !has(item, 'data.icon_type') || !filterRef.current[item.data.icon_type]
    );

    setRg(rg => {
      rg.filteredItems = leftMerge(filteredItems, coloredItems);

      return {
        ...rg,
      };
    });

    setMenuData(menuData => {
      menuData.threshold = threshold;

      return {
        ...menuData,
      };
    });
  }

Функция, которая вызывает ее после нажатия кнопки, которая также обновляет Состояние кнопки es (состояние кнопки передается от объекта фильтра):

function changeCheckBox(id, checked) {
    setFilter(filter => {
      filter[id] = !checked;

      return {
        ...filter,
      };
    });

    filterItems(menuData.threshold);
  }

1 Ответ

0 голосов
/ 14 января 2020

Кажется, вызывая вашу filterItems функцию в , обработчик вызывает ошибку устаревшего состояния, обновление состояния еще не согласовано. Отделите ваши функции, которые обновляют состояние и «прослушивают» обновления до состояния, чтобы запустить функцию фильтра.

Вот демонстрация, которая должна помочь увидеть шаблон:

export default function App() {
  const [filters, setFilters] = useState(filterOptions);

  const onChangeHandler = e => {
    setFilters({ ...filters, [e.target.name]: e.target.checked });
  };

  const filterItems = (threshold, items = {}) => {
    console.log("Gross function that does the filtering");
    console.log("threshold", threshold);
    console.log("items", items);
  };

  useEffect(() => {
    filterItems(42, filters);
  }, [filters]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>

      {Object.entries(filters).map(([filter, checked]) => {
        return (
          <Fragment key={filter}>
            <label htmlFor={filter}>{filter}</label>
            <input
              id={filter}
              name={filter}
              type="checkbox"
              checked={checked}
              onChange={onChangeHandler}
            />
          </Fragment>
        );
      })}
    </div>
  );
}

Edit withered-meadow-qwzmj

Это работает путем удаления обновлений состояния от побочных эффектов состояния. Обработчик обновляет состояние фильтров, всегда возвращая новый объект со следующими значениями фильтра, и ловушка эффекта срабатывает при изменении значения на filters.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...