问题:
According to the docs, "Without middleware, Redux store only supports synchronous data flow" . 根据文档, “没有中间件,Redux存储仅支持同步数据流” 。 I don't understand why this is the case. 我不明白为什么会这样。 Why can't the container component call the async API, and then dispatch the actions? 为什么容器组件不能调用异步API,然后dispatch操作?
For example, imagine a simple UI: a field and a button. 例如,想象一个简单的UI:一个字段和一个按钮。 When user pushes the button, the field gets populated with data from a remote server. 当用户按下按钮时,该字段将填充来自远程服务器的数据。
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>;
}
}
When the exported component is rendered, I can click the button and the input is updated correctly. 渲染导出的组件后,我可以单击按钮,并且输入已正确更新。
Note the update function in the connect call. 注意connect调用中的update功能。 It dispatches an action that tells the App that it is updating, and then performs an async call. 它调度一个动作,告诉应用程序正在更新,然后执行异步调用。 After the call finishes, the provided value is dispatched as a payload of another action. 调用完成后,将提供的值作为另一个操作的有效负载进行分派。
What is wrong with this approach? 这种方法有什么问题? Why would I want to use Redux Thunk or Redux Promise, as the documentation suggests? 如文档所示,我为什么要使用Redux Thunk或Redux Promise?
EDIT: I searched the Redux repo for clues, and found that Action Creators were required to be pure functions in the past. 编辑:我在Redux仓库中搜索了线索,发现过去需要Action Creators是纯函数。 For example, here's a user trying to provide a better explanation for async data flow: 例如, 以下用户试图为异步数据流提供更好的解释:
The action creator itself is still a pure function, but the thunk function it returns doesn't need to be, and it can do our async calls 动作创建者本身仍然是一个纯函数,但是它返回的thunk函数并不需要,它可以执行异步调用
Action creators are no longer required to be pure. 动作创建者不再需要是纯粹的。 So, thunk/promise middleware was definitely required in the past, but it seems that this is no longer the case? 因此,过去肯定需要使用thunk / promise中间件,但似乎不再是这种情况了?
解决方案:
参考一: https://stackoom.com/question/2L3Qs/为什么在Redux中我们需要中间件来实现异步流参考二: https://oldbug.net/q/2L3Qs/Why-do-we-need-middleware-for-async-flow-in-Redux
来源:oschina
链接:https://my.oschina.net/stackoom/blog/4405856
