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

Posted

技术标签:

【中文标题】react+redux 中预加载组件数据的正确方法【英文标题】:Correct way to pre-load component data in react+redux 【发布时间】:2017-01-14 08:30:45 【问题描述】:

我不知道从 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 或类似的生命周期方法来加载数据 - 但是我不需要通过道具传递列表,因为组件总是为自己加载数据,我不希望这样,因为每当创建新组件时,数据都是从 api 获取而不是从 store...

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

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

【问题讨论】:

【参考方案1】:

处理数据预加载的最“类似redux”的方式是在包装您的应用程序的高阶组件的生命周期方法(可能是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;
  

【讨论】:

我意识到这是一个较老的问题,但我希望有人仍然会回应。这似乎是我的问题的解决方案,但我显然仍然做错了什么。 this.props.getDepartments();对我来说抛出和错误。说它不是函数。我是反应新手,react-redux,我不知道如何解决这个问题。任何帮助将不胜感激。 确保在mapDispatchToProps中绑定了函数,并连接到redux store。老实说,不看你写的代码就很难判断...

以上是关于react+redux 中预加载组件数据的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

React + Redux:reducer 不会重新加载组件

(通用 React + redux + react-router)如何避免在初始浏览器加载时重新获取路由数据?

等待带有 React Hooks 的 Redux Action

将firestore onSnapShot与react redux一起使用的正确方法

在 reactjs 组件中预加载数据

React + Redux + Axios 在创建动作后不加载组件