Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应:操作创建者未调用还原程序_Javascript_Reactjs_Redux - Fatal编程技术网

Javascript 反应:操作创建者未调用还原程序

Javascript 反应:操作创建者未调用还原程序,javascript,reactjs,redux,Javascript,Reactjs,Redux,我正在action creator中进行异步调用,并使用结果调用reducer,但由于某些原因,我无法理解reducer没有被调用 actions.js(动作和动作创建者) reducers.js import { GET_FORMS } from '../actions/actions' export default function formAction(state = {forms:[]}, action) { console.log("received action"+action

我正在action creator中进行异步调用,并使用结果调用reducer,但由于某些原因,我无法理解reducer没有被调用

actions.js(动作和动作创建者)

reducers.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
 }
}
App.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)
import React,{Component,PropTypes}来自“React”
从“react dom”导入react dom;
从“redux”导入{bindActionCreators}
从“react redux”导入{connect}
从“../auth”导入身份验证
从“../components/FormTable”导入FormTable
从“../actions/actions”导入*作为动作
类应用程序扩展组件{
建造师(道具){
超级(道具);
this.state={forms:[]};
}
componentDidMount(){
//出于某种原因,如果我写这个.props.actions.getForms(),我会得到一个错误
//未捕获错误:操作必须是普通对象。请使用自定义中间件
//异步操作。
getForms();
}
render(){
const{forms,actions}=this.props
控制台日志(表格);
返回(
)
}
}
App.PropTypes={
表格:PropTypes.array.isRequired
}
函数mapStateToProps(){
常数{
表格:表格
}={forms:[]}
返回{
形式
}
}
功能图DispatchToprops(调度){
返回{
动作:bindActionCreators(动作、调度)
}
}
导出默认连接(
MapStateTops,
mapDispatchToProps
)(应用程序)

您应该使用redux thunk中间件:

本质上,正如您的代码所示——您没有返回符合FSA的操作(实际上现在也没有返回任何内容)。您需要点击发送,然后返回承诺的结果


有关异步操作创建者的更多信息,请参见此处:

这里有一些内容

  • 您的动作创建者不会返回它正在创建的动作
    $.get
    不会返回操作,因此将其映射到
    调度
    是无效的

    合理地说,这可能会导致对如何从异步操作创建者返回操作的困惑。由于它是异步的,本质上它不能返回最终结果(除非您使用的是es7
    async
    wait
    )。您尝试的模式与此相同:

    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
    返回一个 ,而不是任何行动。因此,您必须在回调中使用结果本身——您不能只返回它。下面是
    componentDidMount
    的示例(注意回调绑定到
    this
    ):

  • 在组件或动作创建者中执行异步是一种反模式,或者至少是不鼓励的。在本例中,您将在action creator中定义异步,这非常好。但是您也在执行异步操作,这很糟糕。相反,您应该使用某种中间件来处理异步操作。中间件只是在分派操作之后执行操作和处理操作的函数,最常用的是
    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
    传递给prop的绑定动作创建者——你调用了未绑定的

    因此,您需要调用
    this.props.actions.FormActions()
    ,而不是调用
    FormActions.getForms()
    。前者不受约束,但后者受约束。调用后者与执行
    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()'
    
    这主要是一种样式选择,但我认为这是一种很好的模式:)对于多个action creator源对象,您可以这样做:

    export default connect(mapStateToProps, { ...FormActions, ...UserActions })(App);
    

  • 感谢对redux流如何工作的详细解释,我能够从action creator获取reducer捕获操作,并使用记录器验证是否存在状态更改。但是在App.js的render方法中,表单数组/对象似乎仍然是空的。我是否在mapstatetoprops中出错。是-mapstatetoprops将始终返回空数组。您正在使用解构赋值,所以常量{forms:forms}={forms:[]};将始终是forms=[]。如果使用connect,则需要指定要注入组件的全局状态的哪一部分。您可以在这里阅读有关react用法的更多信息:是的。我发现我没有将表单映射到状态,因此无法获得更改。该链接帮助我将我的状态映射到表单,并在我的渲染方法中显示和获取数据。谢谢!这个解释非常好,非常有用。从文档中学习是一回事,但通过深思熟虑地回顾某人的尝试来学习是另一回事。。。我很感激你不带偏见、乐于助人的语气。真正地这篇帖子把我从“嗯?”带到了“r e d u x w o r k i n g”(是的)
    // 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);