ドキュメントによると、「ミドルウェアがないと、Reduxストアは同期データフローのみをサポートします」 . なぜそうなのかわかりません。コンテナー コンポーネントが非同期 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>;
}
}
エクスポートされたコンポーネントがレンダリングされると、ボタンをクリックすると入力が正しく更新されます。
Note the update
function in the connect
call. 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?
EDIT: I searched the Redux repo for clues, and found that Action Creators were required to be pure functions in the past. 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/promise ミドルウェアが必要だったのですが、そうではなくなったということでしょうか。