最简单的方法是使用
redux-thunkpackage进行操作。这个软件包是一个redux中间件,因此,首先,您应该将其连接到redux:
import { createStore, applyMiddleware } from 'redux';import thunk from 'redux-thunk';import rootReducer from './reducers/index';const store = createStore( rootReducer, applyMiddleware(thunk));这使您可以将
async动作与常规
sync动作一起分派。让我们创建其中之一:
// actions.jsexport function fetchTodos() { // Instead of plain objects, we are returning function. return function(dispatch) { // Dispatching REQUEST action, which tells our app, that we are started requesting todos. dispatch({ type: 'FETCH_TODOS_REQUEST' }); return fetch('/api/todos') // Here, we are getting json body(in our case it will contain `todos` or `error` prop, depending on request was failed or not) from server response // And providing `response` and `body` variables to the next chain. .then(response => response.json().then(body => ({ response, body }))) .then(({ response, body }) => { if (!response.ok) { // If request was failed, dispatching FAILURE action. dispatch({ type: 'FETCH_TODOS_FAILURE', error: body.error }); } else { // When everything is ok, dispatching SUCCESS action. dispatch({ type: 'FETCH_TODOS_SUCCESS', todos: body.todos }); } }); }}我更喜欢在呈现和容器组件上分离React组件。本文完美地描述了这种方法。
接下来,我们应该创建
TodosContainer组件,该组件将为演示
Todos组件提供数据。在这里,我们正在使用
react-redux库:
// TodosContainer.jsimport React, { Component } from 'react';import { connect } from 'react-redux';import { fetchTodos } from '../actions';class TodosContainer extends Component { componentDidMount() { // When container was mounted, we need to start fetching todos. this.props.fetchTodos(); } render() { // In some simple cases, it is not necessary to create separate `Todos` component. You can put todos markup directly here. return <Todos items={this.props.todos} /> }}// This function is used to convert redux global state to desired props.function mapStateToProps(state) { // `state` variable contains whole redux state. return { // I assume, you have `todos` state variable. // Todos will be available in container component as `this.props.todos` todos: state.todos };}// This function is used to provide callbacks to container component.function mapDispatchToProps(dispatch) { return { // This function will be available in component as `this.props.fetchTodos` fetchTodos: function() { dispatch(fetchTodos()); } };}// We are using `connect` function to wrap our component with special component, which will provide to container all needed data.export default connect(mapStateToProps, mapDispatchToProps)(TodosContainer);另外,如果要显示加载程序/错误消息,则应创建
todosReducer,将处理
FETCH_TODOS_SUCCESS操作以及其他2个操作。
// reducers.jsimport { combineReducers } from 'redux';const INITIAL_STATE = { items: [], isFetching: false, error: undefined};function todosReducer(state = INITIAL_STATE, action) { switch (action.type) { case 'FETCH_TODOS_REQUEST': // This time, you may want to display loader in the UI. return Object.assign({}, state, { isFetching: true }); case 'FETCH_TODOS_SUCCESS': // Adding derived todos to state return Object.assign({}, state, { isFetching: false, todos: action.todos }); case 'FETCH_TODOS_FAILURE': // Providing error message to state, to be able display it in UI. return Object.assign({}, state, { isFetching: false, error: action.error }); default: return state; }}export default combineReducers({ todos: todosReducer});对于其它操作喜欢
CREATE,
UPDATE,
DELETE没有什么特别的,他们正在实施方式相同。



