调用异步动作生成器的多重分派
Call to multiple dispatch for async action generators
//Action Generator
export const userActionGenerator = () => {
return function (dispatch) {
axios.get(`https://jsonplaceholder.typicode.com/users`)
.then((resp)=> {
//First Call to Dispatch
dispatch({ type: 'GETUSER', payload: resp.data});
})
}
}
//Component
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { userActionGenerator} from '../store/appStore'
class Users extends Component {
render() {
console.log(this.props)
return (
<div>
Users Component
<button onClick={this.props.getAllUsers}>
Load Users</button>
{this.props.data.map(item => {
return (
<div key={item.id}>
<h1>{item.name}</h1>
</div>
)
})}
</div>
)
}
}
const mapStateToProps = (state, props) => ({data: state.users})
const mapDispatchToProps = dispatch => (
{
getAllUsers: () => {
//Second Call to Dispatch
dispatch(userActionGenerator());
}
}
)
export default connect(mapStateToProps,mapDispatchToProps)(Users);
在没有 "dispatch" 的情况下直接调用 "userActionGenerator" 不会给出任何响应,我可以通过调用调度传递 "userActionGenerator" 函数调用使其工作。
但是我不明白为什么当action generator已经调用了它时,我们还需要在组件中再次调用dispatch。
您的动作创建者实际上是 thunk。
当您 dispatch
它时, redux-thunk middleware 将捕获它并调用它。
正常的动作应该是对象而不是函数,但是 redux-thunk
allows you to dispatch functions:
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
当该函数被 redux-thunk
调用时,它将必须发送一个真正的动作(一个对象),这是您的第二个 dispatch
。
流程是这样的:
dispatch(userActionGenerator());
redux-thunk
会捕获这个因为 userActionGenerator
returns 一个函数而不是一个对象,它会调用返回的函数,
通过它时 (dispatch, getState, extraArgument)
:
return function (dispatch) {
axios.get(`https://jsonplaceholder.typicode.com/users`)
.then((resp)=> {
//First Call to Dispatch
dispatch({ type: 'GETUSER', payload: resp.data});
})
}
这个返回的函数正在调度一个对象,这意味着 redux-thunk
将忽略它并让 reducer(或链下的其他中间件)处理这个动作。
您可能需要使用 bindActionCreators。 Here 是官方文档。请通过它。
import { bindActionCreators } from 'redux';
// Using bindActionCreators you don't need to use dispatch
const mapDispatchToProps = dispatch => bindActionCreators({
// actions
userActionGenerator,
// action1,
// action2,
// ...
}, dispatch);
并且在你的操作文件中你必须这样写。
const userActionGenerator = (...args) => dispatch => {
dispatch(object1);
dispatch(object2);
};
//Action Generator
export const userActionGenerator = () => {
return function (dispatch) {
axios.get(`https://jsonplaceholder.typicode.com/users`)
.then((resp)=> {
//First Call to Dispatch
dispatch({ type: 'GETUSER', payload: resp.data});
})
}
}
//Component
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { userActionGenerator} from '../store/appStore'
class Users extends Component {
render() {
console.log(this.props)
return (
<div>
Users Component
<button onClick={this.props.getAllUsers}>
Load Users</button>
{this.props.data.map(item => {
return (
<div key={item.id}>
<h1>{item.name}</h1>
</div>
)
})}
</div>
)
}
}
const mapStateToProps = (state, props) => ({data: state.users})
const mapDispatchToProps = dispatch => (
{
getAllUsers: () => {
//Second Call to Dispatch
dispatch(userActionGenerator());
}
}
)
export default connect(mapStateToProps,mapDispatchToProps)(Users);
在没有 "dispatch" 的情况下直接调用 "userActionGenerator" 不会给出任何响应,我可以通过调用调度传递 "userActionGenerator" 函数调用使其工作。 但是我不明白为什么当action generator已经调用了它时,我们还需要在组件中再次调用dispatch。
您的动作创建者实际上是 thunk。
当您 dispatch
它时, redux-thunk middleware 将捕获它并调用它。
正常的动作应该是对象而不是函数,但是 redux-thunk
allows you to dispatch functions:
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
当该函数被 redux-thunk
调用时,它将必须发送一个真正的动作(一个对象),这是您的第二个 dispatch
。
流程是这样的:
dispatch(userActionGenerator());
redux-thunk
会捕获这个因为 userActionGenerator
returns 一个函数而不是一个对象,它会调用返回的函数,
通过它时 (dispatch, getState, extraArgument)
:
return function (dispatch) {
axios.get(`https://jsonplaceholder.typicode.com/users`)
.then((resp)=> {
//First Call to Dispatch
dispatch({ type: 'GETUSER', payload: resp.data});
})
}
这个返回的函数正在调度一个对象,这意味着 redux-thunk
将忽略它并让 reducer(或链下的其他中间件)处理这个动作。
您可能需要使用 bindActionCreators。 Here 是官方文档。请通过它。
import { bindActionCreators } from 'redux';
// Using bindActionCreators you don't need to use dispatch
const mapDispatchToProps = dispatch => bindActionCreators({
// actions
userActionGenerator,
// action1,
// action2,
// ...
}, dispatch);
并且在你的操作文件中你必须这样写。
const userActionGenerator = (...args) => dispatch => {
dispatch(object1);
dispatch(object2);
};