为什么这个createAsyncThunk表现奇怪?

时间:2020-11-11 08:23:03

标签: javascript reactjs redux redux-toolkit

我在redux工具包API中对此createAsyncThunk遇到了一些问题

export const getPayments = createAsyncThunk('getPayments/all', async ({ rejectWithValue }) => {
    try {
        const response = await fetch(`/payments`, {
            method: 'GET',
            headers: { 'Content-Type': 'application/json' },
        })
        console.log('res:', response)
        return response
    } catch (e) {
        console.log('ERROR:', e)
        rejectWithValue(e)
    }
})

每当我添加rejectWithValue作为参数时,它总是显示为在redux devtools中被拒绝。当我删除它时,它一定会实现。这里发生了什么?如果提取时发生错误,我只想在下面调用此函数?为什么总是拒绝呢?

编辑:我现在在响应中看到这个Cannot destructure property 'rejectWithValue' of 'undefined' as it is undefined.,这很有意义,为什么它总是被拒绝,为什么会这样,但是我该如何解决?

1 个答案:

答案 0 :(得分:0)

这里是一个示例,payload creatorrejectWithValue第二个参数的属性,并且有效载荷创建者需要返回 rejectWithValue调用的结果,下面是一个示例:

// toggle reject
const reject = ((shouldReject) => () =>
  (shouldReject = !shouldReject))(true);
// test thunk action creator
const testAsyncThunk = createAsyncThunk(
  'some/test',
  //  arg is the argument passed to the action creator, can be ignored if not used
  async (arg, { rejectWithValue }) => {
    console.log('argument passed to action creator:', arg);
    if (reject()) {
      //return result of rejectWithValue call
      return rejectWithValue('rejected');
    }
    return Promise.resolve('resolved');
  }
);

除非您使用createAsyncThunk,否则当您调度使用unwrapResult创建的thunk时,会产生will not reject的承诺。

以下是演示行为的最小应用程序:

import React from 'react';
import ReactDOM from 'react-dom';
import {
  createAsyncThunk,
  unwrapResult,
} from '@reduxjs/toolkit';

import { Provider, useDispatch } from 'react-redux';
import {
  createStore,
  applyMiddleware,
  compose,
} from 'redux';

// toggle reject
const reject = ((shouldReject) => () =>
  (shouldReject = !shouldReject))(true);
// test thunk action creator
const testAsyncThunk = createAsyncThunk(
  'some/test',
  //  arg is the argument passed to the action creator, can be ignored if not used
  async (arg, { rejectWithValue }) => {
    console.log('argument passed to action creator:', arg);
    if (reject()) {
      //return result of rejectWithValue call
      return rejectWithValue('rejected value');
    }
    return Promise.resolve('resolved value');
  }
);

const reducer = (state, { type, payload }) => {
  return state;
};
//creating store with redux devtools and thunk middleware
const composeEnhancers =
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducer,
  {},
  composeEnhancers(
    applyMiddleware(
      ({ dispatch, getState }) => (next) => (action) =>
        //minimal implementation of thunk middleware
        typeof action === 'function'
          ? action(dispatch, getState)
          : next(action)
    )
  )
);
const App = () => {
  const dispatch = useDispatch();
  return (
    <button
      onClick={() =>
        dispatch(testAsyncThunk('argument passed'))
          .then(
            (resolved) => {
              console.log('action resolved with', resolved);
              return resolved;
            },
            (rejected) =>
              // this never executes because promise returned
              //   by dispatch(tunkaction) will not reject
              console.log('action rejected with:', rejected)
          )
          .then(
            //after unwrap result you have a promise that will
            //  reject
            unwrapResult
          )
          .catch((err) =>
            console.log('rejected with...', err)
          )
      }
    >
      dispatch action
    </button>
  );
};

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);