Правильный способ предварительной загрузки данных компонентов в 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-thunk и mapDispatchToProps ввести fetchDepartments в компонент без состояния и реализовать componentWillMount или аналогичный метод жизненного цикла для загрузки данных-но тогда мне не нужно передавать список через реквизит, так как компонент всегда загружает данные для себя, и я этого не хочу, потому что всякий раз, когда создается новый компонент, данные извлекаются из api вместо store...

еще один совет, который я видел-это использовать getComponent функция от react-router и retreive все данные перед возвращением компонента, однако, я не уверен, что это правильный способ redux, так как я не вижу, как использовать redux-thunk там и логика вроде как замусорена всеми файлами, когда это данные, необходимые только для одного компонента.

это оставляет мне единственный, казалось бы, ок вариант загрузки данных в методы жизненного цикла компонента контейнера, но я хочу знать, что считается лучшей практикой для того, что я хочу сделать.

1 ответов


самый "redux-подобный" способ обработки предварительной загрузки данных - запустить асинхронное действие в методе жизненного цикла (вероятно,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;
  }
}