taro icon indicating copy to clipboard operation
taro copied to clipboard

createAsyncThunk创建的action无法使用dispatch

Open hikzhang opened this issue 1 year ago • 12 comments

相关平台

微信小程序

小程序基础库: 3.4.1 使用框架: React

复现步骤

  1. 在slice中定义foo = createAsyncThunk(...),并在createSlice的extrareducers中使用build.addCase(foo.pending...)等
  2. 在页面中使用dispatch(foo)

期望结果

foo定义的async functionf

实际结果

执行时报错:AbortController is not defined

ReferenceError: AbortController is not defined
    at vendors-node_modules_taro_weapp_prebundle_reduxjs_toolkit_js.js?t=wechat&s=1713083731279&v=c3009756f740784f3e1fbc8afa686d9b:2359
    at vendors-node_modules_taro_weapp_prebundle_reduxjs_toolkit_js.js?t=wechat&s=1713083731279&v=c3009756f740784f3e1fbc8afa686d9b:1525
    at vendors-node_modules_taro_weapp_prebundle_reduxjs_toolkit_js.js?t=wechat&s=1713083731279&v=c3009756f740784f3e1fbc8afa686d9b:1790
    at vendors-node_modules_taro_weapp_prebundle_reduxjs_toolkit_js.js?t=wechat&s=1713083731279&v=c3009756f740784f3e1fbc8afa686d9b:1614
    at Object.current (index.tsx?cf8d:13)
    at Object.callback (vendors-node_modules_taro_weapp_prebundle_tarojs_plugin-framework-react_dist_runtime_js.js?t=wechat&s=1713083731279&v=dc9330fe3530ade2dc87a23f82bc3b47:96)
    at vendors-node_modules_taro_weapp_prebundle_chunk-H5CKLZB7_js.js?t=wechat&s=1713083731279&v=1f79f6e1c526573bda1897e0aa961ea9:1131
    at Array.map (<anonymous>)
    at safeExecute (vendors-node_modules_taro_weapp_prebundle_chunk-H5CKLZB7_js.js?t=wechat&s=1713083731279&v=1f79f6e1c526573bda1897e0aa961ea9:1131)
    at AppWrapper.<anonymous> (vendors-node_modules_taro_weapp_prebundle_chunk-H5CKLZB7_js.js?t=wechat&s=1713083731279&v=1f79f6e1c526573bda1897e0aa961ea9:1209)(env: macOS,mp,1.06.2402040; lib: 3.4.1)

环境信息

taro info
👽 Taro v3.6.26

(node:65681) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)

  Taro CLI 3.6.26 environment info:
    System:
      OS: macOS 14.4.1
      Shell: 5.9 - /bin/zsh
    Binaries:
      Node: 21.7.2 - /opt/homebrew/bin/node
      npm: 10.5.0 - /opt/homebrew/bin/npm
    npmPackages:
      @tarojs/cli: 3.6.26 => 3.6.26
      @tarojs/components: 3.6.26 => 3.6.26
      @tarojs/helper: 3.6.26 => 3.6.26
      @tarojs/plugin-framework-react: 3.6.26 => 3.6.26
      @tarojs/plugin-platform-alipay: 3.6.26 => 3.6.26
      @tarojs/plugin-platform-h5: 3.6.26 => 3.6.26
      @tarojs/plugin-platform-jd: 3.6.26 => 3.6.26
      @tarojs/plugin-platform-qq: 3.6.26 => 3.6.26
      @tarojs/plugin-platform-swan: 3.6.26 => 3.6.26
      @tarojs/plugin-platform-tt: 3.6.26 => 3.6.26
      @tarojs/plugin-platform-weapp: 3.6.26 => 3.6.26
      @tarojs/react: 3.6.26 => 3.6.26
      @tarojs/runtime: 3.6.26 => 3.6.26
      @tarojs/shared: 3.6.26 => 3.6.26
      @tarojs/taro: 3.6.26 => 3.6.26
      @tarojs/taro-loader: 3.6.26 => 3.6.26
      @tarojs/webpack5-runner: 3.6.26 => 3.6.26
      babel-preset-taro: 3.6.26 => 3.6.26
      eslint-config-taro: 3.6.26 => 3.6.26
      react: ^18.0.0 => 18.2.0

补充信息

实际taro版本是3.6.26(无可选项)

hikzhang avatar Apr 16 '24 04:04 hikzhang

解决方法: 1,安装这俩包:yet-another-abortcontroller-polyfill,event-target-polyfill 2,app.js import: import 'event-target-polyfill'; import 'yet-another-abortcontroller-polyfill';

seekerliu avatar Apr 21 '24 11:04 seekerliu

感谢!按你的解决方法成功运行了。

不过是否应该从Taro框架本身引入才更好呢。

hikzhang avatar Apr 22 '24 04:04 hikzhang

我按照seekerliu https://github.com/seekerliu 提供的解决方案已经可以正常使用了。

On May 8, 2024, at 15:40, 悟 @.***> wrote:

兄弟,我的不是报错,而是无法捕捉结果。不知道是啥原因,你们之前使用成功了吗?

Taro v3.6.28

extraReducers: (builder) => { builder.addCase(fetchUser.pending, (state, action) => { console.log(action) }); builder.addCase(fetchUser.rejected, (state, action) => { console.log(action) }); // Add reducers for additional action types here, and handle loading state as needed builder.addCase(fetchUser.fulfilled, (state, action) => { console.log('success', action) }) } — Reply to this email directly, view it on GitHub https://github.com/NervJS/taro/issues/15517#issuecomment-2099947523, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFA7VLX6G2AEYL7MJBD25DLZBHJH5AVCNFSM6AAAAABGIQ5H7KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJZHE2DONJSGM. You are receiving this because you authored the thread.

hikzhang avatar May 09 '24 08:05 hikzhang

@hikzhang 我遇到的问题是,模拟器正常,真机调试dispatch之后action没有执行。我的是抖音小程序。

mrold avatar May 17 '24 01:05 mrold

装了以后直接白屏了

解决方法: 1,安装这俩包:yet-another-abortcontroller-polyfill,event-target-polyfill 2,app.js import: import 'event-target-polyfill'; import 'yet-another-abortcontroller-polyfill';

mrold avatar May 17 '24 01:05 mrold

重新启动看看呢?似乎有些编译缓存不会被更新到。

On May 17, 2024, at 09:57, 悟 @.***> wrote:

装了以后直接白屏了

解决方法: 1,安装这俩包:yet-another-abortcontroller-polyfill,event-target-polyfill 2,app.js import: import 'event-target-polyfill'; import 'yet-another-abortcontroller-polyfill';

— Reply to this email directly, view it on GitHub https://github.com/NervJS/taro/issues/15517#issuecomment-2116489957, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFA7VLTSE5UEZNZGBY2JCJTZCVPY3AVCNFSM6AAAAABGIQ5H7KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMJWGQ4DSOJVG4. You are receiving this because you were mentioned.

hikzhang avatar May 17 '24 13:05 hikzhang

遇到了同样的问题,感谢 @seekerliu

luankefei avatar Jun 05 '24 03:06 luankefei

装了以后直接白屏了

解决方法: 1,安装这俩包:yet-another-abortcontroller-polyfill,event-target-polyfill 2,app.js import: import 'event-target-polyfill'; import 'yet-another-abortcontroller-polyfill';

解决了吗,我也是装完白屏

moxiaonai avatar Jul 19 '24 03:07 moxiaonai

装了以后直接白屏了

解决方法: 1,安装这俩包:yet-another-abortcontroller-polyfill,event-target-polyfill 2,app.js import: import 'event-target-polyfill'; import 'yet-another-abortcontroller-polyfill';

解决了吗,我也是装完白屏

我放弃了,移除了redux

mrold avatar Jul 19 '24 04:07 mrold

装了以后直接白屏了

解决方法: 1,安装这俩包:yet-another-abortcontroller-polyfill,event-target-polyfill 2,app.js import: import 'event-target-polyfill'; import 'yet-another-abortcontroller-polyfill';

解决了吗,我也是装完白屏

我放弃了,移除了redux

我这边解决了,后面遇到的同学可以参考,微信小程序应该是可以通过上述的polyfill方案解决 抖音小程序因为限制了globalThis和window的访问,pollyfill不行,引入那两个包以后会白屏,通过分析可以知道这个报错的主要原因是createAsyncThunk里面维护的promise abort状态导致的,可以通过绕过createAsyncThunk来解决,比如:

  1. 手动维护请求的状态
  2. 或者用redux-thunk之类的库去维护异步请求状态就可以避免了 参考:
import { createSlice } from '@reduxjs/toolkit';
import axios from 'axios';

const initialState = {
  data: null,
  loading: false,
  error: null,
  // 添加一个额外的字段
  userId: null, // 假设我们需要使用这个字段来决定是否请求数据
};

const mySlice = createSlice({
  name: 'mySlice',
  initialState,
  reducers: {
    fetchStart: (state) => {
      state.loading = true;
      state.error = null;
    },
    fetchSuccess: (state, action) => {
      state.loading = false;
      state.data = action.payload;
    },
    fetchError: (state, action) => {
      state.loading = false;
      state.error = action.payload;
    },
    setUserId: (state, action) => {
      state.userId = action.payload;
    },
  },
});

export const { fetchStart, fetchSuccess, fetchError, setUserId } = mySlice.actions;

// 修改后的 fetchData,读取 state
export const fetchData = () => async (dispatch, getState) => {
  const state = getState(); // 读取当前 state
  const { userId } = state.mySlice; // 从 state 中获取 userId
  
  // 如果 userId 不存在或无效,则不进行请求
  if (!userId) {
    console.warn('User ID is required for this request');
    return;
  }

  dispatch(fetchStart()); // 请求开始,设置 loading 为 true
  try {
    const response = await axios.get(`https://api.example.com/data/${userId}`); // 使用 state 中的 userId
    dispatch(fetchSuccess(response.data)); // 请求成功,设置 data 和 loading 状态
  } catch (error) {
    dispatch(fetchError(error.toString())); // 请求失败,设置 error 和 loading 状态
  }
};

export default mySlice.reducer;

moxiaonai avatar Jul 23 '24 08:07 moxiaonai

现在好多库都有依赖AbortController 上面的方法尝试过无效,官方有什么更好的方案吗?

hengkx avatar Jul 27 '24 03:07 hengkx