Redux Thunk + ReactJS:调用了动作创建器,但未调用调度函数

时间:2018-11-18 12:13:11

标签: javascript reactjs redux react-redux

我的ReactJS x Redux应用程序遇到一个非常奇怪的问题,这是我从未见过的,并且很难弄清。

在我的ReactJS组件中,我连接了一个动作创建者函数,该函数正在使用redux-thunk和对象{中的connect()函数,使用react-redux进行异步调用。 {1}}表示法。看起来像这样:

mapDispatchToProps

为简单起见,假设const mapStateToProps = (state) => ({ ...state.single_pano }); const mapDispatchToProps = { loadPano }; export default connect(mapStateToProps, mapDispatchToProps)(PanoView); 动作创建者看起来像这样:

loadPano

这是很奇怪的地方:

在我的export const loadPano = (id) => { console.log('Action creator called.'); return async (dispatch) => { console.log('Dispatch function called.'); const doc = await db.doc('/path/to/doc/'+id).get(); dispatch({ type: 'LOAD_ACTION', payload: doc }); } } 生命周期函数中,我正在对componentDidMount()进行调用,该调用完全按预期工作(调用了动作创建者中的两个this.props.loadPano(panoID)调用,{{1} } / console.log()返回并将动作分派给reducer。

稍后,我需要在组件的async生命周期函数中再次调用await,因为URL参数已更改,并且某些数据需要获取并重新加载。 但是,这次最终发生的是调用了动作创建者(this.props.loadPano(panoID)),但从未调用过componentWillReceiveProps()调度功能(loadPano)。我可以说是这种情况,因为第一个redux-thunk被调用,但是第二个从未被登录到控制台。

我正在做的其他一些与众不同的事情可能与之相关,但是到目前为止,我还无法确认其中的任何一个:

  • return (dispatch) => { ... }组件利用console.log()生命周期方法来控制DOM的呈现时间。
  • 我有点不讲究/不是最佳实践-使用PanoView组件状态之外的变量来存储第3方库对象,该对象可以直接通过DOM shouldComponentUpdate()修改DOM,而且实际上不能与ReactJS一起正确使用。但是我相信这是孤立的,无法看到它将如何干扰Redux / Thunk。尤其是因为调度功能会在第一次正确触发。

相关依赖项+版本(通过PanoView安装):

ref

请求的更新:

我的yarn组件的"firebase": "^5.2.0", "photo-sphere-viewer": "^3.4.0", "react": "^16.4.1", "react-dom": "^16.4.1", "react-redux": "^5.0.7", "react-router-dom": "^4.3.1", "redux": "^4.0.0", "redux-thunk": "^2.3.0" 生命周期函数如下:

componentWillReceiveProps

1 个答案:

答案 0 :(得分:1)

当我们对您的代码一无所知时,很难(几乎不可能)猜测问题出在哪里。您的RemotingServices.GetObjectUri(myLoadedTypeInstance)看起来如何?

这是一个好习惯,可能会引起混乱:

componentWillReceiveProps

Redux thunk本质上是一种检查每个调度动作的中间件。如果该操作返回一个函数,则它将调用该函数,然后将const mapDispatchToProps = { loadPano }; dispatch参数传递给返回的函数,然后还将调用此函数。

所以我的猜测是:

  1. state中,您正在呼叫componendDidMount
  2. this.props.loadPano(id)中,您仅呼叫componentWillReceiveProps

第一个是loadPano并进入化简器。第二个就是store.dispatch(loadPano)并返回一个承诺。 (您的动作创建者)