操作 Thunk 未触发 createAsyncThunk

时间:2021-02-18 17:55:26

标签: redux fetch redux-thunk redux-toolkit

我正在尝试在 createAsyncThunk 内部进行提取,但即使在另一个 createAsyncThunk 中使用了相同的代码结构并且提取运行良好,也未触发提取。当我在 extraReducer 中使用 console.log(action) 时,它会抛出此消息:

error:
message: "[Immer] Immer only supports setting array indices and the 'length' property"
name: "Error"
stack: "Error: [Immer] Immer only supports setting array indices and the 'length' property↵    at t (http://localhost:3001/static/js/0.chunk.js:2362:11)↵    at Object.push../node_modules/@reduxjs/toolkit/node_modules/immer/dist/immer.esm.js.et.set (http://localhost:3001/static/js/0.chunk.js:3282:59)↵    at create-comment/pending (http://localhost:3001/static/js/main.chunk.js:3604:29)↵    at http://localhost:3001/static/js/0.chunk.js:1272:20↵    at e.i.produce (http://localhost:3001/static/js/0.chunk.js:3317:13)↵    at http://localhost:3001/static/js/0.chunk.js:1271:71↵    at Array.reduce (<anonymous>)↵    at http://localhost:3001/static/js/0.chunk.js:1238:25↵    at combination (http://localhost:3001/static/js/0.chunk.js:45726:29)↵    at p (<anonymous>:1:36402)↵    at v (<anonymous>:1:36684)↵    at <anonymous>:1:40069↵    at Object.dispatch (http://localhost:3001/static/js/0.chunk.js:45479:22)↵    at e (<anonymous>:1:40553)↵    at http://localhost:3001/static/js/0.chunk.js:946:22↵    at http://localhost:3001/static/js/0.chunk.js:45239:16↵    at http://localhost:3001/static/js/0.chunk.js:798:32↵    at dispatch (http://localhost:3001/static/js/0.chunk.js:45906:28)↵    at http://localhost:3001/static/js/0.chunk.js:2042:13↵    at _catch (http://localhost:3001/static/js/0.chunk.js:1834:18)↵    at http://localhost:3001/static/js/0.chunk.js:2029:24↵    at http://localhost:3001/static/js/0.chunk.js:2069:8↵    at http://localhost:3001/static/js/0.chunk.js:45236:18↵    at Object.dispatch (http://localhost:3001/static/js/0.chunk.js:798:32)↵    at dispatch (<anonymous>:1:28545)↵    at sendToApiComment (http://localhost:3001/static/js/main.chunk.js:1597:29)↵    at sendNewComment (http://localhost:3001/static/js/main.chunk.js:1210:11)↵    at HTMLUnknownElement.callCallback (http://localhost:3001/static/js/0.chunk.js:13360:18)↵    at Object.invokeGuardedCallbackDev (http://localhost:3001/static/js/0.chunk.js:13409:20)↵    at invokeGuardedCallback (http://localhost:3001/static/js/0.chunk.js:13469:35)↵    at invokeGuardedCallbackAndCatchFirstError (http://localhost:3001/static/js/0.chunk.js:13484:29)↵    at executeDispatch (http://localhost:3001/static/js/0.chunk.js:17719:7)↵    at processDispatchQueueItemsInOrder (http://localhost:3001/static/js/0.chunk.js:17751:11)↵    at processDispatchQueue (http://localhost:3001/static/js/0.chunk.js:17764:9)↵    at dispatchEventsForPlugins (http://localhost:3001/static/js/0.chunk.js:17775:7)↵    at http://localhost:3001/static/js/0.chunk.js:17986:16↵    at batchedEventUpdates$1 (http://localhost:3001/static/js/0.chunk.js:31671:16)↵    at batchedEventUpdates (http://localhost:3001/static/js/0.chunk.js:13158:16)↵    at dispatchEventForPluginEventSystem (http://localhost:3001/static/js/0.chunk.js:17985:7)↵    at attemptToDispatchEvent (http://localhost:3001/static/js/0.chunk.js:15468:7)↵    at dispatchEvent (http://localhost:3001/static/js/0.chunk.js:15386:23)↵    at unstable_runWithPriority (http://localhost:3001/static/js/0.chunk.js:47163:16)↵    at runWithPriority$1 (http://localhost:3001/static/js/0.chunk.js:20766:14)↵    at discreteUpdates$1 (http://localhost:3001/static/js/0.chunk.js:31688:18)↵    at discreteUpdates (http://localhost:3001/static/js/0.chunk.js:13170:16)↵    at dispatchDiscreteEvent (http://localhost:3001/static/js/0.chunk.js:15352:7)"
__proto__: Object
meta: {arg: {…}, requestId: "UjmyfmxeslFCy4C4FPSzc", rejectedWithValue: false, requestStatus: "rejected", aborted: false, …}
payload: undefined
type: "create-comment/rejected"

createAsyncThunk 是这样写的:

const initCreator = (verb, data = null) => {
  let result;
  if (data) {
    result = {
      method: verb,
      mode: 'cors',
      cache: 'no-cache',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json',
      },
      redirect: 'follow',
      referrerPolicy: 'no-referrer',
      body: JSON.stringify(data),
    };
  } else {
    result = {
      method: verb,
      mode: 'cors',
      cache: 'no-cache',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json',
      },
      redirect: 'follow',
      referrerPolicy: 'no-referrer',
    };
  }
  return result;
};    

const createComment = createAsyncThunk('create-comment', async data => {
      const init = initCreator('POST', data.item);
      const response = await fetch(`${URL}comments`, init)
        .then(data => data.json())
        .catch(error => error.json());
      return { reduxId: data.reduxId, response };
    });

这是注释 createSlice 部分:

const initialState = {
  comments: [],
  error: null,
  status: 'idle',
};
const comments = createSlice({
  name: 'comments',
  initialState,
  reducers: {
    removeErrorComments: state => { state.error = null; },
  },
  extraReducers: {
    [retrieveComments.pending]: state => { state.status = 'pending'; },
    [retrieveComments.fulfilled]: (state, action) => {
      console.log(action.payload.response);
      // some code that is commented out
    },
    [retrieveComments.rejected]: (state, action) => {
      state.status = 'failed retrieve';
      state.error = action.payload;
    },
    [createComment.pending]: state => { state.comments.status = 'pending'; },
    [createComment.fulfilled]: (state, action) => {
      console.log(state, action);
     // some code that is commented out
    },
    [createComment.rejected]: (state, action) => {
      console.log(action);
      state.status = 'Failed creation comment, rejected action';
      state.error = `Something went wrong, please notify us with this error: ${action.payload}`;
    },
  },
});

thunk 被触发后,这会显示在 Redux Store 中:

comments(pin): []
error(pin):"Something went wrong, please notify us with this error: undefined"
status(pin):"Failed creation comment, rejected action"

我想了解的是为什么没有触发提取,我做错了什么?在此先感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:0)

导致该错误的情况是:

[createComment.pending]: state => { state.comments.status = 'pending'; },

state 这里指的是这个切片的状态,所以 state.comments 是一个数组。当您尝试在数组上设置属性 status 时,您会收到关于如何只允许数组的某些属性的错误。

您想改为设置 state.status

[createComment.pending]: state => { state.status = 'pending'; },

由于初始值为 state.error,因此在设置 null 时出现了一个无关的打字稿错误。您需要为您的状态定义一个类型,它允许 errornull,但也允许其他值。