我有以下搜索组件
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});
})
}
但是它会抛出一个错误,即没有定义调度。可能是因为我没有在组件中的任何地方传递它。
答案 0 :(得分:5)
由于这是一个异步操作,因此您需要使用中间件来处理在不同时间调度多个操作。
动作创建者本质上是同步的,因此这就是为什么在响应从您的请求中返回时调度同步动作所必需的中间件。
为了掌握这一点,我建议你使用redux-thunk,比主要的替代redux-promise中间件库更容易掌握。
Redux Thunk中间件
Redux Thunk中间件允许您编写返回函数而不是动作的动作创建者。
首先在商店配置期间设置您的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作为参数的函数。
Thunk action creator
function fetchThing(url) {
return (dispatch) => {
/*dispatch more actions*/
}
}
这样做的好处是我们的组件可以调度异步操作,就像它们是同步的一样,不需要传递调度功能,因此不需要了解Redux存储。
redux-thunk中间件知道在我们创建它之后拦截我们的thunk动作,传递调度,以便将来的操作(如RESPONSE_RECEIVED操作)可以访问调度。
为了使用redux-thunk,创建一个动作创建器,它返回一个函数,该函数按照上述方式接受dispatch作为参数。
示例强>
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承诺和Redux Thunk的替代方案
现在还有其他方法可以控制异步数据流。然而,在我看来,redux-thunk简单方便。 Redux Promise是Redux Thunk的一个很好的替代品。这里的区别在于redux-promise是中间件,拦截返回承诺而不是thunk的动作创建者。
但是严格来说,在redux中,对于异步流,你根本不需要中间件。它的优点是将数据流集中在一个地方,使您的组件更加分离,因为它们不需要明确地传递Redux的商店调度方法,因此不关心< em>如何创建和动作。
有关Redux中间件的深入讨论,请参阅Dan Abramov的this answer,了解为什么我们需要在redux中使用异步流的中间件,
答案 1 :(得分:1)
我正在使用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()时使用表单数据调用的函数 从表单组件中触发。如果您没有将其指定为 在这里,你必须将它作为参数传递给handleSubmit()里面 你的表单组件。
如果你的onSubmit函数返回一个promise,那就是提交属性 将被设置为true,直到承诺得到解决或拒绝。 如果它被包含错误的redux-form SubmissionError拒绝 以{field1:'error',field2:'error'}的形式然后提交 错误将被添加到每个字段(到错误道具),就像异步一样 验证错误是。如果存在不特定的错误 任何领域,但适用于整个表格,你可以传递,如同 这是一个名为_error的字段的错误,它将作为 错误道具。
将使用以下参数调用onSubmit:
values:Object
{field1:'value1',field2:'value2'形式的字段值 }。
调度:功能
Redux调度功能。
props:Object
道具传递到您的装饰组件。
http://redux-form.com/6.2.0/docs/api/ReduxForm.md/
TBH我仍然没有得到动作创建者内部的调度以及为什么之前的建议(我尝试过)不起作用。来自更熟悉该主题的人的评论会很好。
答案 2 :(得分:0)
TBH我仍然没有得到动作创建者内部的调度以及为什么以前的建议(我尝试过)不起作用。来自更熟悉该主题的人的评论会很好。
(道歉,没有足够的代表发表评论)
redux-form的handleSubmit
似乎始终将dispatch
(从其自己的props
参数派生)作为第二个参数传递给您提供的提交函数(请参阅{ {3}})
我认为这通常是undefined
,但是thunk(如果存在的话)会使dispatch
可用于redux-form,因此也适用于你。