使用钩子在onClick Event React中等待父状态更改

时间:2020-07-09 19:39:16

标签: javascript reactjs promise react-redux react-hooks

我面临的问题如下。

我有一个React无状态下拉组件,它公开了onClick方法。

当触发此onClick方法时,我更改了下拉状态,该状态再次传递给相同的下拉组件。

下拉菜单如下:

def func1(s):
    return s;

当前onDropdownToggleClick方法如下:

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

现在,我有一个状态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'); } }; 来自React组件中的redux存储。每15秒获取一次数据,这是一个布尔值。

现在的要求是,切换下拉菜单(onDropdownToggleClick)且fetchingfetching时,我必须将dropdownState设置为'fetching'并等待其变为true 。当它变为假时,只有我必须执行该语句

false

现在的问题是,获取操作是由redux处理的,它没有给出我可以等待的承诺。

我尝试做两件事:

1-

const requests = await EnvironmentsAPI.getEnvironmentActiveRequests(
  environmentId
);

然后有一个useEffect,其中我像这样打开下拉列表

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');
    }
  }
};

但是这里的问题是每15秒轮询一次获取,并且大多数情况下它是错误的。每15秒钟最多更改为true 1秒。因此,即使提取环境的API不完整,大多数情况下我的下拉菜单还是“打开”的。

2-我尝试以某种方式手动创建一个Promise,该Promise将在获取更改时解决。仅在切换下拉菜单时才会创建此承诺。

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

现在,这个诺言立即得到解决。我尝试将这个诺言保留在useRef中。

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'); } }; 最初是未定义的,那么它将等待下一个提取周期(15秒)才更新。

任何线索或其他方法都将非常有帮助。谢谢。

让我知道我是否无法解释我的问题。

0 个答案:

没有答案