实战首页:首页数据的异步获取

481 阅读3分钟

首先我们需要定义一个异步请求,从后端服务器接口获取数据,然后根据返回的 JSON 数据,通过发送对应的 Action 来改变 State 的状态。

下面是一个模拟请求 JSON 数据并使用这些数据渲染页面的例子,类似这样的一个 JSON 数据:

{
  "topicList": [
    { "id": 1, "title": "Topic 1" },
    { "id": 2, "title": "Topic 2" }
  ],
  "articleList": [
    { "id": 1, "title": "Article 1" },
    { "id": 2, "title": "Article 2" }
  ],
  "recommendList": [
    { "id": 1, "title": "Recommend 1" },
    { "id": 2, "title": "Recommend 2" }
  ]
}

1. 初始代码

以下是初始代码:

componentDidMount() {
  axios.get('/api/home.json').then((res) => {
     const result = res.data.data;
     const action = {
       type: 'change_home_data',
       topicList: result.topicList,
       articleList: result.articleList,
       recommendList: result.recommendList
     };
     this.props.changeHomeData(action);
   })
}

2 优化组件逻辑

上面的代码中,在 UI 组件的生命周期函数 componentDidMount 中发送 Ajax 请求并修改 State,这并不是一个好的实践,我们应该将逻辑处理放在一个函数中,然后只调用这个函数来执行操作,这样可以让组件更加简洁。

以下是优化后的代码:

javascriptCopy code
componentDidMount() {
  this.props.changeHomeData();
}

这个函数中的操作实际上是创建一个 Action 并将其分发到 Reducer 进行数据更新。具体实现如下:

javascriptCopy code
const mapDispatchToProps = (dispatch) => ({
  changeHomeData() {
    const action = actionCreators.getHomeInfo();
    dispatch(action);
  }
});

Reducer 处理如下:

phpCopy code
import { fromJS } from 'immutable';
import * as constants from './constants';

const defaultState = fromJS({
  topicList: [],
  articleList: [],
  recommendList: []
});

export default (state = defaultState, action) => {
  switch (action.type) {
    case constants.CHANGE_HOME_DATA: {
      console.log(action);
      return state.merge({
        topicList: fromJS(action.topicList),
        articleList: fromJS(action.articleList),
        recommendList: fromJS(action.recommendList)
      });
    }
    default: {
      return state;
    }
  }
}

3. 异步请求的发送

在上面的代码中,我们使用了thunk中间件来允许在action中进行异步操作。具体的实现可以在actionCreators中看到:

javascriptCopy code
import axios from "axios";
import * as constants from './constants';

const changeHomeData = (result) => ({
  type: constants.CHANGE_HOME_DATA,
  topicList: result.topicList,
  articleList: result.articleList,
  recommendList: result.recommendList
});

export const getHomeInfo = () => {
  return (dispatch) => {
    axios.get('/api/home.json').then((res) => {
      const result = res.data.data;
      dispatch(changeHomeData(result));
    })
  }
};

上面的代码中,changeHomeData函数实际上是一个真正发送的action。在getHomeInfo函数中,我们使用异步请求来获取JSON中需要的数据并创建并分发一个对应的action来更新store的状态。

4. 回顾thunk

当我们需要在 Redux 中进行异步操作时,可以使用 Redux 中间件来处理异步行为。其中,Redux Thunk 是一种常用的中间件,它允许我们在 action creators 中返回一个函数而不是一个普通的 action 对象。

这个函数接收两个参数:dispatch 和 getState。dispatch 是用于派发 action 的函数,而 getState 是用于获取当前的 state 的函数。这样,在异步操作中,我们就可以在 action creator 中进行一些异步操作,例如通过 axios 发送异步请求,等待请求响应后再通过 dispatch 发送一个真正的 action。

在上面的代码中,我们定义了一个名为 getHomeInfo 的 action creator,它返回了一个函数。在这个函数中,我们发送了一个异步请求来获取远程数据,并在响应后通过 dispatch 发送一个名为 changeHomeData 的 action 来更新 store 中的数据。

在 Redux 中使用 Thunk 可以让我们更方便地处理异步操作,而不必在组件中处理异步操作逻辑。同时,使用 Thunk 还可以使代码更加简洁易懂。