如何从 React 组件 Redux Toolkit 中的 createAsyncThunk 获取结果

How to get result from createAsyncThunk in React component Redux Toolkit

我正在从 Apollo 客户端迁移到 Redux 工具包,我很困惑如何使用 API 与 createAsyncThunk 调用的结果(成功或错误)并调用 history.push('/')setSubmitting(false) 在我的 React 组件中。

我如何处理 FormikApollo Client 的示例:

      onSubmit={async (values, { setSubmitting }) => {
    signInMutation({
      variables: {
        email: values.email,
        password: values.password,
      },
    }).then(
      (response) => {
        if (response.data.signIn.accessToken) {
          localStorage.setItem(
            AUTH_TOKEN,
            response.data.signIn.accessToken,
          );
          if (response.data.signIn.User.isNew) {
            history.push('/welcome-page');
          } else {
            history.push('/');
          }
          setSubmitting(false);
        }
      },
      (err) => {
        console.log(`error signin ${err}`);
        enqueueSnackbar(err.message, {
          variant: 'error',
        });
        setSubmitting(false);
      },
    );

当您调用 createAsyncThunk 时,它将 return 一个 redux-thunk 可以使用的 Action Creator

你应该像这样使用函数:

const actionCreator = createAsyncThunk('prefix', async function echo(text) {
  return text;
});

// app.js
import { unwrapResult } from '@reduxjs/toolkit';

function App() {
  const dispatch = useDispatch();

  return (
    <button
      onClick={() => {
        dispatch(actionCreator('233'))
          .then(unwrapResult)
          .then((result) => {
            console.log(result); // => 233
          })
          .catch((error) => {
            console.error(error); // if there is an error
          });
      }}
    >
      Echo
    </button>
  );
}

这就是 unwrapResult 的作用:

// @reduxjs/toolkit
export function unwrapResult<R extends ActionTypesWithOptionalErrorAction>(
  returned: R
): PayloadForActionTypesExcludingErrorActions<R> {
  if ('error' in returned) {
    throw returned.error
  }
  return (returned as any).payload
}

要处理错误,有两种方法。第一种是直接扔,第二种是return rejectWithValue.

async function echo(text, { rejectWithValue }) {
  if (Math.random() < 0.5) {
    // throw new Error('error msg');
    // return rejectWithValue('error value');
  }
  return text;
}

dispatch(actionCreator('233'))
  .then(unwrapResult)
  .then((result) => {
    console.log(result); // => 233
  })
  .catch((error) => {
    // by throw new Error('error msg');
    console.log(error.message); // => error msg
    // by return rejectWithValue('error value')
    console.log(error); // => error value
  });