【问题标题】:How to pass Dispatch to action when using redux form使用 redux 表单时如何将 Dispatch 传递给操作
【发布时间】:2016-12-19 03:07:55
【问题描述】:

我有以下搜索组件

import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';

import { search } from '../../actions/actions'

class Search extends Component {

    render() {
        const {handleSubmit, "fields":{query}} = this.props;

        return (
            <div>
                <form onSubmit={handleSubmit(search)}>
                    <Field className='searchInput' name="query" component="input" type="text" placeholder="Enter course name"/>
                    <button className='searchSubmit' type='submit' >Search</button>
                </form>
            </div>
        );
    }
}
export default reduxForm({
    "form":"searchForm",
    "fields":["query"]
}, null, {search})(Search);

我的搜索操作是这样的

search : function(query){
    var data = {
        ep:"EP_SEARCH",
        payload:{
            query: query.query
        }
    }

    getAsynch(data).then(function(result){
        return {type: GET_DATA, payload:result};
    })
}

我从端点得到响应,但我需要以某种方式调度操作。

我试过而不是

getAsynch(data).then(function(result){
            return {type: GET_DATA, payload:result};
        })

这个

return function(dispatch){
    getAsynch(data).then(function(result){
        dispatch({type: GET_DATA, payload:result});
    })
}

但它会抛出一个未定义调度的错误。可能是因为我没有在组件中的任何地方传递它。

【问题讨论】:

标签: reactjs redux react-redux redux-form


【解决方案1】:

由于这是一个异步操作,您需要使用中间件来处理在不同时间分派多个操作。

动作创建者本质上是同步的,因此这就是为什么需要中间件以便在将来从您的请求返回响应时调度同步动作。

为了更好地掌握,我建议您使用 redux-thunk,因为它比主要的替代 redux-promise 中间件库更容易掌握。

Redux Thunk 中间件

Redux Thunk 中间件允许您编写返回函数而不是动作的动作创建器。

首先在你的 store 配置过程中设置你的 redux-thunk 中间件

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);

现在 redux-thunk 知道如何处理特殊 thunk 动作的调度

thunk 动作只是一个动作,它返回另一个以 dispatch 作为参数的函数。

Tunk 动作创建者

    function fetchThing(url) { 
        return (dispatch) => {
             /*dispatch more actions*/
        }
    }

这样做的好处是我们的组件可以像同步一样调度异步操作,并且不需要传递调度函数,因此不需要了解 Redux 存储。

redux-thunk 中间件知道在我们创建它之后拦截我们的 thunk 动作,并传入 dispatch 以便未来的动作(例如 RESPONSE_RECEIVED 动作)可以访问调度。

为了使用 redux-thunk 创建一个动作创建器,它返回一个函数,该函数按照上述接受调度作为参数。

示例

function epSearch(query){
    // thunk passes dispatch into the function below 
    // so that future actions will have access to dispatch

    return function(dispatch){

         // below function needs to return a promise in order for us to call .then
        getAsynch(data).then(   
          result => dispatch({ type: GET_DATA, payload:result }),
          error dispatch({ type: REQUEST_ERROR, payload: error })
        );
    };
}

如果由于错误而未解决承诺,则我们的 REQUEST_ERROR 操作将被调度,并且该操作的有效负载将是我们从被拒绝的承诺中收到的错误

Redux Promise 和 Redux Thunk 的替代方案

现在还有其他方法可以控制您的异步数据流。然而,在我看来 redux-thunk 既简单又方便。 Redux Promise 是 Redux Thunk 的一个很好的替代品。这里的区别在于 redux-promise 是中间件,它拦截返回 Promise 而不是 thunk 的动作创建者。

但是严格来说,你在 redux 中根本不需要中间件来实现异步流。它的优点是将数据流集中在一个地方,这允许您的组件更加解耦,因为它们不需要显式传递 Redux 的 store 的 dispatch 方法,因此不关心 如何 和操作已创建。

有关 Redux 中的中间件的深入讨论,请参阅 Dan Abramov 的 this answer,关于为什么我们需要中间件用于 redux 中的异步流,

【讨论】:

  • 我正在为此使用 Redux Thunk。以下是解决我问题的答案。我不知道调度是如何传递给动作的。最佳猜测 - 魔术。
【解决方案2】:

我正在使用 Redux Thunk,并且我的操作对除 ReduxForm 之外的所有内容都适用。在阅读了很多关于该主题的内容后,如果发现了解决方案。

search : function(query, dispatch){ //APPARENTLY DISPATCH IS THE SECOND PARAMETER, WHICH WAS MISSING IN MY INITIAL FUNCTION
        var data = {
            ep:"EP_SEARCH",
            payload:{
                query: query.query
            }
        }
        getAsynch(data).then((result)=>{
            dispatch({ type: GET_DATA, payload:result })
        });
    }

关于该主题的更多信息

onSubmit : 函数 [可选]

handleSubmit() 被调用时使用表单数据调用的函数 从表单组件中触发。如果您不将其指定为 这里的prop,你必须把它作为参数传递给handleSubmit()里面 你的表单组件。

如果您的 onSubmit 函数返回一个承诺,则提交属性 将设置为 true 直到 promise 被解决或拒绝。 如果它被包含错误的 redux-form SubmissionError 拒绝 格式为 { field1: 'error', field2: 'error' } 然后提交 错误将被添加到每个字段(到错误道具),就像异步一样 验证错误是。如果有错误不是特定于 任何字段,但适用于整个表单,您可以将其传递为 这是一个名为 _error 的字段的错误,它将被给出为 错误属性。

onSubmit 将使用以下参数调用:

值:对象

{ field1: 'value1', field2: 'value2' 形式的字段值 }。

调度:函数

Redux 调度函数。

道具:对象

传递到装饰组件的道具。

http://redux-form.com/6.2.0/docs/api/ReduxForm.md/

TBH 我仍然不明白 dispatch 是如何进入动作创建者的,以及为什么我之前尝试过的建议不起作用。来自更熟悉该主题的人的评论会很好。

【讨论】:

    【解决方案3】:

    TBH 我仍然不明白 dispatch 是如何进入动作创建者的,以及为什么我之前尝试过的建议不起作用。来自更熟悉该主题的人的评论会很好。

    (抱歉,没有足够的代表发表评论)

    redux-form 的 handleSubmit 似乎总是将 dispatch(源自它自己的 props 参数)作为第二个参数传递给您提供的提交函数(参见 https://github.com/erikras/redux-form/blob/master/src/handleSubmit.js

    我会假设这通常是 undefined,但是如果存在 thunk,它将使 dispatch 可用于 redux-form 并因此对您可用。

    【讨论】:

      猜你喜欢
      • 2019-02-18
      • 2019-09-14
      • 2020-08-14
      • 1970-01-01
      • 2021-02-07
      • 2019-05-17
      • 2018-05-09
      • 2019-05-27
      • 2011-09-07
      相关资源
      最近更新 更多