反应:动作创建者不调用化简器
React : Action creator not calling reducer
我正在我的动作创建器中进行异步调用并使用结果调用我的化简器,但由于某种原因,我无法理解没有调用化简器。
操作.js(操作和操作创建者(
export const GET_FORMS = 'GET_FORMS'
export function getForms() {
$.get("server url", function(result) {
return {
type: GET_FORMS,
formlist: result.data.forms
}
})
}
减速器.js
import { GET_FORMS } from '../actions/actions'
export default function formAction(state = {forms:[]}, action) {
console.log("received action"+action.type)
switch (action.type) {
case GET_FORMS:
console.log("Action:"+action);
return Object.assign({},state,{
forms:action.formlist
})
default:
return state
}
}
应用.js
import React, { Component, PropTypes } from 'react'
import ReactDOM from 'react-dom';
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import auth from '../auth'
import FormTable from '../components/FormTable'
import * as FormActions from '../actions/actions'
class App extends Component {
constructor(props) {
super(props);
this.state = {forms: []};
}
componentDidMount() {
// for some reason if i write this.props.actions.getForms () i get an error
// Uncaught Error: Actions must be plain objects. Use custom middleware for
// async actions.
FormActions.getForms();
}
render() {
const {forms,actions} = this.props
console.log(forms);
return (
<FormTable results={forms} actions = {actions} />
)
}
}
App.PropTypes = {
forms: PropTypes.array.isRequired
}
function mapStateToProps() {
const {
forms:forms
} = {forms:[]}
return {
forms
}
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(FormActions, dispatch)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App)
几件事。
操作创建者不会返回它正在创建的操作。
$.get
不会返回操作,因此将其映射到dispatch
效率不高。合理地,这可能会导致对如何从异步操作创建者返回操作感到困惑。由于它是异步的,因此本质上它无法返回最终结果(除非您使用 es7
async
await
(。您尝试的模式与此相同:class App extends Component { ... componentDidMount() { // Instead of calling getForms, do the same directly $.get(url, function(res) { return { type: GET_FORMS, forms: res }; }); } render() { ... } }
从
$.get
api 我们知道$.get
返回一个jqXHR
对象,而不是任何类型的操作。所以你必须在回调中使用结果本身 - 你不能只返回它。下面是一个示例,说明componentDidMount
可能看起来像什么样子(请注意,回调绑定到this
(:componentDidMount() { $.get(url, function(res) { this.props.dispatch({ type: GET_FORMS, forms: res }); }.bind(this)) }
在组件或操作创建器中执行异步是一种反模式,或者至少不鼓励这样做。在本例中,您将在动作创建器中定义异步,这很棒。但是你也在执行异步操作,这很糟糕。相反,您应该使用某种中间件来处理异步操作。中间件只是在调度后执行操作并对其执行操作的功能,为此目的最常见的是
redux-thunk
.使用redux-thunk
,您只需返回一个接受dispatch
作为参数的函数。在本例中,动作创建者将如下所示:export function getForms() { return function(dispatch) { $.get(url, function(result) { dispatch({ type: GET_FORMS, forms: result }); }) } }
这与你已经在做的事情非常相似,只是你正在创建一个
thunk
- 它只是一个定义另一个函数以供以后执行的函数 - 而不是现在实际执行异步操作,你正在定义它以便稍后执行。你实际上并没有调度任何东西。
最容易解决的问题,但绝对是一个障碍:)在
componentDidMount
中,您正在调用已导入的动作创建者,但不会调用dispatch
。虽然你已经完成了50%的路程,因为你把动作创造者传给了connect
,但即使你这样做了,你也没有把connect
传递到道具的绑定动作创造者称为绑定的动作创造者——你称之为未绑定的。所以与其打电话给
FormActions.getForms()
,不如叫this.props.actions.formActions()
。前者不受约束,但后者受约束。调用后者与执行this.props.dispatch(FormActions.getForms())
相同。最后:在这种情况下,您不需要定义
mapDispatchToProps
。您可以将对象传递给该参数connect
。见下文:// Instead of this export default connect(mapStateToProps, mapDispatchToProps)(App); // do this: export default connect(mapStateToProps, FormActions)(App); // creates the bound action creator 'this.props.getForms()'
这个主要是一种风格选择,但我认为这是一个很好的模式:)对于多动作创建器源对象,您可以执行以下操作:
export default connect(mapStateToProps, { ...FormActions, ...UserActions })(App);
你应该使用 redux-thunk 中间件:https://github.com/gaearon/redux-thunk
基本上就像您的代码一样 - 您没有返回符合 FSA 的操作(实际上现在没有返回任何内容(。您需要抛出调度,然后返回承诺的结果。
有关异步动作创建者的更多信息,请点击此处:http://redux.js.org/docs/advanced/AsyncActions.html
- 如何使jQuery插件函数可调用以供独立使用,而不在集合上操作
- D3在一个调用中绘制不同的SVG形状,没有可见性
- 如何从Java/scala调用js美化程序
- 如何调用这个匿名 JavaScript 函数
- 如何从模块链中调用函数.导出到节点中
- 我需要从php调用javascript或jquery
- Chrome开发工具(如何知道我在调用哪个javascript对象)
- 单击按钮后如何逐个调用分区,上一个分区将隐藏
- 另一个ajax调用中的Jquery ajax调用在for循环中没有按预期工作
- Twitter Bootstrap typeahead:使用“this”获取上下文/调用元素
- node.js:setInterval()正在跳过调用
- 如何在单击复选框后调用控制器方法
- 如何在JQuery函数中定义一个值,然后调用另一个函数并使用该值
- 使用Google Visualization动态调用构造函数
- 如何在webView,Android中从@JavascriptInterface方法调用Javascript
- 是否可以将一个函数输入连接到另一个函数调用的文本
- 调用函数内部的函数
- 我可以在React和Redux中发送一个AJAX调用,而不需要操作创建者和还原器吗
- Redux 操作创建者在另一个内部调用一个
- 反应:动作创建者不调用化简器