react+redux预加载组件数据的正确方式

Correct way to pre-load component data in react+redux

我不知道从 API 预加载数据以供组件使用的正确方法。

我写了一个无状态组件来渲染数据:

import React, { PropTypes } from 'react';

const DepartmentsList = ({ departments }) => {
  const listItems = departments.map((department) => (
    <li><a href="./{department}">{department.title}</a></li>
  ));
  return (
    <ul>
      {listItems}
    </ul>
  );
};

DepartmentsList.propTypes = {
  departments: PropTypes.array.isRequired
};

export default DepartmentsList;

我有一个操作将从 API:

中检索数据
import { getDepartments } from '../api/timetable';

export const REQUEST_DEPARTMENTS = 'REQUEST_DEPARTMENTS';
export const RECEIVE_DEPARTMENTS = 'RECEIVE_DEPARTMENTS';

const requestDepartments = () => ({ type: REQUEST_DEPARTMENTS });
const receiveDepartments = (departments) => ({ type: RECEIVE_DEPARTMENTS, departments });

export function fetchDepartments() {
  return dispatch => {
    dispatch(requestDepartments);
    getDepartments()
      .then(departments => dispatch(
        receiveDepartments(departments)
      ))
      .catch(console.log);
  };
}

现在我想我有几个选项可以预加载列表所需的部门。我可以使用 redux-thunkmapDispatchToProps 将 fetchDepartments 注入无状态组件并实现 componentWillMount 或类似的生命周期方法来加载数据——但是我不需要通过 props 传递列表,因为组件总是会为自己加载数据,而我不希望这样,因为无论何时创建新组件,都会从 api 而不是存储...

中获取数据

我看到的另一个建议是使用来自 react-router 的 getComponent 函数,并在返回组件之前检索所有数据,但是,我不确定它是否是正确的 redux 方式,因为我不知道在那里看不到如何使用 redux-thunk,当只有一个组件需要数据时,逻辑似乎散落在文件中。

这给我留下了在容器组件的生命周期方法中加载数据的唯一看似可行的选项,但我想知道什么是我想做的事情的最佳实践。

最 'redux-like' 处理数据预加载的方法是在包装您的应用程序的高阶组件的生命周期方法(可能 componentWillMount)中触发异步操作.但是,您不会在该组件中直接使用 API 调用的结果 - 它需要使用将其放入您的应用程序商店的缩减程序进行处理。这将要求您使用某种 thunk 中间件来处理异步操作。然后,您将使用 mapStateToProps 将其简单地传递给呈现数据的组件。

高阶组件:

const mapStateToProps = (state) => {
  return {
    departments: state.departments
  };
}

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators({
    getDepartments: actionCreators.fetchDepartments
  });
}

class App extends Component {
  componentWillMount() {
    this.props.getDepartments();
  }

  render() {
    return <DepartmentsList departments={this.props.departments} />
  }
}

 export default connect(mapStateToProps, mapDispatchToProps)(App);

减速器:

export function departments(state = [], action) {
  switch(action.type) {
    case 'RECEIVE_DEPARTMENTS':
      return action.departments;
  }
}