Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用时出现action in action的小问题 1.0.0 #20

Closed
smartPiz opened this issue Jun 28, 2022 · 23 comments
Closed

使用时出现action in action的小问题 1.0.0 #20

smartPiz opened this issue Jun 28, 2022 · 23 comments
Labels
bug Something isn't working

Comments

@smartPiz
Copy link

模拟器里正常
真机预览提示action in action
但是代码里只有state.xxx=yyy
我还在找原因

@smartPiz
Copy link
Author

effect异步里返回的时候有处action ,我在想是不是这俩冲突了。因为我把在page里初始化时action移到effect里 就正常了。

@smartPiz
Copy link
Author

page A 点击按钮 执行model.effect 异步结果写入 state.info = abc ,同时点击按钮时弹出弹窗,弹窗里显示 state.info 。 弹窗初始的时候useEffect(()=>model.action)

这样就会出错了。得把model.action移到model.effect里面。 但这俩逻辑又不一样,放一起有点怪。

@smartPiz smartPiz changed the title 小程序用着有点问题 1.0.0 使用时出现action in action的小问题 1.0.0 Jun 28, 2022
@geekact
Copy link
Member

geekact commented Jun 29, 2022

出现action in action 一般是因为在action方法内部执行了其它action或者effect方法。我看下有没有遗漏的场景。你这边也看下有没有办法提供一个可复现的repo

@geekact
Copy link
Member

geekact commented Jun 29, 2022

抱歉,我这里暂时没看出什么问题。
另外我发布了1.0.1版本使得报错信息中能同时展示冲突的action和上次执行的action,建议你升级后再试一次

@smartPiz
Copy link
Author

抱歉,我这里暂时没看出什么问题。 另外我发布了1.0.1版本使得报错信息中能同时展示冲突的action和上次执行的action,建议你升级后再试一次

好的我先更新一下

@smartPiz
Copy link
Author

抱歉,我这里暂时没看出什么问题。 另外我发布了1.0.1版本使得报错信息中能同时展示冲突的action和上次执行的action,建议你升级后再试一次

错误提示是对的,model.effect 异步返回结果时调用action更新state, 和 在page里的useEffect里调用action初始某个state 发生冲突了。

@smartPiz
Copy link
Author

更新一个issus 以前没有提示的地方现在也有个提示了。就是在model.effect 异步结果里_this.action会提示不存在属性action。

@geekact geekact added the bug Something isn't working label Jun 29, 2022
@geekact
Copy link
Member

geekact commented Jun 29, 2022

排查比较困难,能否提供一个可复现的简易repo?

@geekact
Copy link
Member

geekact commented Jun 29, 2022

更新一个issus 以前没有提示的地方现在也有个提示了。就是在model.effect 异步结果里_this.action会提示不存在属性action。

effect不能使用箭头函数,以及异步回调需要使用箭头函数,才能保证this的正确性

@smartPiz
Copy link
Author

smartPiz commented Jun 29, 2022

贴代码吧。也有可能是我写的有问题 见谅。
Taro 3.4.9 。

PageA.jsx

const btnClick = () => {
    someModel.doEffect(params)
    someModel.openModalAction(true)
}

<Modal open={model.open} />

SomeModel.js

effects: {
        async getSomeApiInfo(cid) {
            var _this = this;
            await Taro.request({
                method: 'POST',
                url: 'https://url',
                data:{
                },
                success(res) {
                    _this.setAction(res.data)
         
                }
            });
           
        }
},

actions:{
    setAction(state,val){
        state.somekey=val
    },
    openModalAction(state,val){
        state.open = val
    },
   setAnotherAction(state,val){
       state.otherkey=val
   }
}

Page Modal.js

//这里要初始一些modal页里的数据
useEffect(()=>{
    someModel.setAnotherAction(val)
},[])

这样写的话,点击按钮modal出现的时候模拟器正常,手机上就会分发错误,但是如果把modal里useEffect里的移到 _this.setAction(res.data)这句后面 就没事了

@geekact
Copy link
Member

geekact commented Jun 29, 2022

写法没有问题,建议先切换到0.12.3(功能一致),我本地再测试一下。

另外再提供一下测试手机的系统和版本

@smartPiz
Copy link
Author

ios 和 微信 都最新版本

@smartPiz
Copy link
Author

微信库是2.24.7

@geekact
Copy link
Member

geekact commented Jun 29, 2022

node_modules/foca/dist/esm/index.js 第 476-483行的try-finally 代码替换成下面这段试试

              try {
                    dispatching = true;
                    prevAction = action;
                    var result = dispatch2(action);
                    prevAction = null;
                    dispatching = false;
                    return result;
                } catch (e) {
                    prevAction = null;
                    dispatching = false;
                    throw e;
                }

我怀疑小程序不支持finally,但是没有证据,家里没办法真机调试

@smartPiz
Copy link
Author

好的 我现在试一下

@geekact
Copy link
Member

geekact commented Jun 30, 2022

好的 我现在试一下

找到一篇之前看的文章,应该和这个问题类似:https://forum.cocos.org/t/ios-bug-jsc-await-promise-mircotasks/83275

我这边也复现了,同步执行的操作被插入了其它操作。

@smartPiz
Copy link
Author

smartPiz commented Jun 30, 2022

我好像说错了action,但是情况一样,地图regionChange时执行一个action 把区域更新到model里,然后在地图界面useEffect(()=>{apiEffect},[newregion])
effect返回的api数据少 就没问题,如果多的话就会提示分发错误,提前这个effect里的action未完成

@geekact
Copy link
Member

geekact commented Jun 30, 2022

大概找到原因了,redux更新完数据后,会遍历subscriber并执行,其中react-redux也订阅了,react-redux那边检测到数据变化然后执行了一下forceUpdate,导致useEffect被提前处理。我估计taro升级到react@18之后,这个问题能自动修复

所以目前有两个方式:

  1. 去除action in action 的功能,因为本身也就是一个规范辅助。
  2. 花点时间重构一下

你那边暂时解决的思路可以这么做:

useEffect(() => {
  Promise.resolve().then(() => {
     model.action();
  });
}, []);

@smartPiz
Copy link
Author

好,感谢

@geekact
Copy link
Member

geekact commented Jun 30, 2022

已经发布 v1.0.2 解决了这个问题,如果没问题则关闭此issue

@smartPiz
Copy link
Author

加油

@smartPiz
Copy link
Author

晚点试一下

@smartPiz
Copy link
Author

nice job

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants