通过观察状态变化来解决handleSubmit的诺言

问题描述

我已经增强了Context的派发,类似于this blog post中所述。此外,就像Redux一样,我可以创建一个中间件链,我的所有操作都将通过该中间件链进行。基于来自Real World Redux的this middleware示例,我有一个中间件可以集中处理所有API消耗。

这意味着我的组件调度动作来发起API请求,并且不能轻易地观察到表示异步操作的Promise。因此,我无法将该承诺传递给RFF的handleSubmit。相反,我需要创建自己的异步函数以传递给handleSubmit并通过观察应用程序状态的变化来解决其诺言。

@erikras创建了Redux Promise Listener,它使用中间件观察调度的动作来解决类似的问题。

我首先创建了一个React钩子,该钩子通过观察状态变化来实现诺言,但感觉很尴尬:

/**
 * usePromiseSettler invokes an async executor function,and then will observe changes in
 * state to determine when the async function's promise has settled. Once settled,* either the success or failure callback will be invoked.
 *
 * @param executor Function that initiates state change we wish to observe
 * @param successCondition Condition that indicates executor operation succeeded
 * @param successCallback Callback to invoke when executor operation succeeds
 * @param failureCondition Condition that indicates executor operation has failed
 * @param failureCallback Callback to invoke when executor operation fails
 * @returns An async function returning a promise which will be settled when
 * a success or error condition is observed.
 */
export const usePromiseSettler = (
  executor: (...args: any[]) => any,successCondition: boolean,successCallback: (value?: any) => void,failureCondition: boolean,failureCallback: (value?: any) => void,) => {
  const resolveRef = useRef<(value?: any) => void>();
  const successConditionRef = useRef<boolean>(false);
  const failureConditionRef = useRef<boolean>(false);

  const staticExecutor = React.useCallback(executor,[]);

  const handlePromise = React.useCallback(
    (value) => {
      staticExecutor(value);
      return new Promise((resolve) => {
        resolveRef.current = resolve;
      });
    },[staticExecutor],);

  if (!successConditionRef.current && successCondition) {
    successCallback(resolveRef.current);
  }

  if (!failureConditionRef.current && failureCondition) {
    failureCallback(resolveRef.current);
  }

  successConditionRef.current = successCondition;
  failureConditionRef.current = failureCondition;

  return handlePromise;
};

用法:

const previousDidCreateSucceed = usePrevious(
    state.targetState.didCreateSucceed,);

const previousError = usePrevious(state.targetState.error);

const handleSubmit = usePromiseSettler(
    (target: TargetData) => {
      const action = requestPostTarget(target);
      dispatch(action);
    },!previousDidCreateSucceed && state.targetState.didCreateSucceed,(resolve) => {
      resolve(state.targetState.data);
      history.push("/targets");
    },!previousError && !!state.targetState.error,(resolve) => {
      resolve({ [FORM_ERROR]: state.targetState.error });
    },);

  ...
  return (
      <Form
        onSubmit={handleSubmit}

这个问题是否已经以更低的复杂度在其他地方解决了?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)