Подождите, пока родительское состояние изменится в onClick Event React, используя хуки - PullRequest
2 голосов
/ 09 июля 2020
• 1000 снова передается тому же раскрывающемуся компоненту.

Выпадающий компонент выглядит следующим образом:

<DynamicDropdown
    dropdown={dropdownData}
    state={dropdownState}
    onToggleClick={onDropdownToggleClick}
    onDismissDropdown={onDismissDropdown}
/>

В настоящее время метод onDropdownToggleClick выглядит следующим образом:

const [dropdownState, setDropdownState] = useState<DropdownState>();
const onDropdownToggleClick = async (s: DropdownState) => {
  if (s === 'closed') {
    setDropdownState('fetching');
    const requests = await EnvironmentsAPI.getEnvironmentActiveRequests(
      environmentId
    );
    setActiveRequests(requests);
    setDropdownState('open');
  } else {
    setDropdownState('closed');
  }
};

Теперь я есть требование, чтобы у меня было одно состояние fetching, исходящее из хранилища redux в моем компоненте React. Это извлекает некоторые данные каждые 15 секунд и является логическим значением.

Теперь требуется, чтобы при переключении раскрывающегося списка (onDropdownToggleClick) и fetching было true я должен установить для моего dropdownState значение 'fetching' и подождите, пока он станет false. Когда он становится ложным, то только я должен выполнить оператор

const requests = await EnvironmentsAPI.getEnvironmentActiveRequests(
  environmentId
);

Теперь проблема в том, что выборка выполняется с помощью redux и не дает обещания, которого я могу ждать.

I попробовал сделать 2 вещи:

1 -

const onDropdownToggleClick = async (s: DropdownState) => {
  setEnvironmentToggled(true);
  if (fetching) {
    setDropdownState('fetching');
  } else {
    if (s === 'closed') {
      setDropdownState('fetching');
      const requests = await EnvironmentsAPI.getEnvironmentActiveRequests(
        environmentId
      );
      setActiveRequests(requests);
      setDropdownState('open');
    } else {
      setDropdownState('closed');
    }
  }
};

, а затем есть useEffect, в котором я открываю раскрывающийся список, например

useEffect(() => {
  if (!fetching) {
    setDropdownState('open');
  }
},[]);

Но проблема здесь в получении опрашивается каждые 15 секунд и в большинстве случаев является ложным. Каждые 15 секунд он изменяется на true на 1 секунду при макс. Поэтому в большинстве случаев мой раскрывающийся список становится «открытым», даже если API для выборки сред не завершен.

2 - Я пытаюсь каким-то образом вручную создать обещание, которое разрешится при получении изменений. Это обещание будет создано только при переключении раскрывающегося списка.

const [fetchingResolve, setFetchingResolve] = useState<
  (value?: unknown) => void
>();
useEffect(() => {
  if (!fetching && fetchingResolve) {
    fetchingResolve();
  }
}, [fetching, fetchingResolve]);
const onDropdownToggleClick = async (s: DropdownState) => {
  if (s === 'closed') {
    setDropdownState('fetching');
    const fetchingPromise = new Promise(resolve => {
      setFetchingResolve(resolve);
    });
    await fetchingPromise;
    const requests = await EnvironmentsAPI.getEnvironmentActiveRequests(
      environmentId
    );
    setActiveRequests(requests);
    setDropdownState('open');
  } else {
    setDropdownState('closed');
  }
};

Теперь это обещание обрабатывается немедленно. Я попытался сохранить это обещание в использовании Ссылка

const fetchingResolve = useRef<(value?: unknown) => void>();
useEffect(() => {
  console.log(fetchingResolve.current);
  if (!fetching && fetchingResolve.current) {
    fetchingResolve.current();
  }
}, [fetching, fetchingResolve.current]);
const onDropdownToggleClick = async (s: DropdownState) => {
  if (s === 'closed') {
    setDropdownState('fetching');
    const fetchingPromise = new Promise(resolve => {
      fetchingResolve.current = resolve;
    });
    await fetchingPromise;
    const requests = await EnvironmentsAPI.getEnvironmentActiveRequests(
      environmentId
    );
    setActiveRequests(requests);
    setDropdownState('open');
  } else {
    setDropdownState('closed');
  }
};

Это сработало частично. Проблема заключалась в том, что если fetchingResolve.current изначально не определен, он будет ждать следующего цикла выборки (15 секунд) перед обновлением.

Любые зацепки или другой подход будут очень полезны. Спасибо.

Сообщите мне, если я не смогу объяснить свою проблему.

...