根据文档,“没有中间件,Redux存储只支持同步数据流”。我不明白为什么会这样。为什么容器组件不能调用async API,然后dispatch
操作?
例如,想象一个简单的UI:一个字段和一个按钮。当用户按下按钮时,该字段将填充来自远程服务器的数据。
import * as React from 'react';import * as Redux from 'redux';import { Provider, connect } from 'react-redux';
const ActionTypes = {STARTED_UPDATING: 'STARTED_UPDATING',UPDATED: 'UPDATED'};
class AsyncApi {static getFieldValue() {const promise = new Promise((resolve) => {setTimeout(() => {resolve(Math.floor(Math.random() * 100));}, 1000);});return promise;}}
class App extends React.Component {render() {return (<div><input value={this.props.field}/><button disabled={this.props.isWaiting} onClick={this.props.update}>Fetch</button>{this.props.isWaiting && <div>Waiting...</div>}</div>);}}App.propTypes = {dispatch: React.PropTypes.func,field: React.PropTypes.any,isWaiting: React.PropTypes.bool};
const reducer = (state = { field: 'No data', isWaiting: false }, action) => {switch (action.type) {case ActionTypes.STARTED_UPDATING:return { ...state, isWaiting: true };case ActionTypes.UPDATED:return { ...state, isWaiting: false, field: action.payload };default:return state;}};const store = Redux.createStore(reducer);const ConnectedApp = connect((state) => {return { ...state };},(dispatch) => {return {update: () => {dispatch({type: ActionTypes.STARTED_UPDATING});AsyncApi.getFieldValue().then(result => dispatch({type: ActionTypes.UPDATED,payload: result}));}};})(App);export default class extends React.Component {render() {return <Provider store={store}><ConnectedApp/></Provider>;}}
当呈现导出的组件时,我可以单击按钮并正确更新输入。
请注意connect
调用中的update
函数。它分派一个操作,告诉应用程序它正在更新,然后执行异步调用。调用完成后,提供的值作为另一个操作的有效负载被分派。
这种方法有什么问题?为什么我要像留档建议的那样使用Redux Thunk或Redux Promise?
编辑:我在Redux仓库里搜了一下线索,发现以前要求Action Creators是纯函数。比如这是一个用户试图为异步数据流提供更好的解释:
动作创建者本身仍然是一个纯函数,但它返回的thunk函数不需要是,它可以执行我们的异步调用
动作创作者不再需要纯粹。所以,过去肯定需要thunk/Promise中间件,但现在似乎不再是这样了?