我不知道从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而不是商店中提取的......
我看到的另一个建议是使用react-router中的getComponent
函数,并在返回组件之前检索所有数据,但是,我不确定它是否是正确的redux方式因为我没有看到如何在那里使用redux-thunk,并且当它只是一个组件所需的数据时,逻辑类似于文件中的所有内容。
这为我提供了在容器组件的生命周期方法中加载数据的唯一看似正常的选项,但我想知道什么是我想要做的最佳实践。
答案 0 :(得分:12)
最像&reduct-like&#39;处理数据预加载的方法是在包装应用程序的高阶组件的生命周期方法(可能是componentWillMount
)中触发异步操作。但是,您不会直接在该组件中使用API调用的结果 - 需要使用将其放入应用商店的reducer进行处理。这将要求您使用某种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;
}
}