四、react-redux的异步网络请求操作

582 阅读2分钟

1. 安装

// 保证状态管理redux封装
npm install redux
// 使react 和 redux 更好的使用
npm install react-redux
// 为了让dispatch能接收一个函数完成异步操作
npm install redux-thunk

2. store创建

import { createStore, applyMiddleware } from 'redux'
import reducer from './reducer'

import thunk from 'redux-thunk'

// 接收一个reducer函数
// 为了让dispatch一个函数,需要添加一个中间件
const store = createStore(reducer, applyMiddleware(thunk))

export default store

3. reducer函数

// 避免每个常量被分解
import * as actionTypes from './constants'

const initialState = {
  counter: 0,
  banners: [],
  recommends: []
}

// 这是一个纯函数,返回值是一个新的state 通过dispatch(action) 修改数据
function reducer(state, action) {
    switch(action.type) {
        // 这里一般用单独的文件常量
        case: actionTypes.CHANGE_COUNTER:
        return {...state, counter: state.counter + action.num}
        
        case: actionTypes.CHANGE_BANNERS:
        return {...state, banners: action.banners}
        
        case: actionTypes.CHANGE_RECOMMENDS:
        return {...state, recommends: action.recommends}
        
        default:
        return state
    }
}

export default reducer

4. 常量文件constants

export const CHANGE_COUNTER = 'change_counter'
export const CHANGE_BANNERS = 'change_banners'
export const CHANGE_RECOMMENDS = 'change_recommends'

5. 在某个组件中使用

import React, { PureComponent } from "react"
import { connect } from 'react-redux'

export class Home extends PureComponent {
    // 节点完成挂载数据请求
    // 为了让数据请求逻辑与组件逻辑进行解耦
    componentDidMount() {
        this.props.fetchBannerList();
    }
    render() {
        // 已经对store里面的数据做了props的映射
        const { banners } = this.props
        return (
            <div className='wrap'>
                <ul>
                    {
                        banners.map((item, index) => {
                            return <li key={index}>{item.title}</li>
                        })
                    }
                </ul>
            </div>
        )
    }
}

// connect是一个函数,调用的时候返回一个高阶函数,该高阶函数接收一个组件为参数
// connect函数本身有两个函数参数,分别对store里面的state数据和dispatch数据做映射操作
const mapStateToProps = (state) => ({
    banners: state.banners
})

// 轮播图数据来自异步请求
const mapDispatchToProps = (dispatch) => ({
    fetchBannerList() {
        console.log('Home组件在生命周期里该函数会被触发')
        // 这里dispatch的时候,reducer函数会被重新执行
        // 这里本应该传递一个action {type: 'XXX', num}
        // fetchBannerListAction() 会生成一个action, 但是想让他生成一个函数
        // 借助redux-thunk 中间件完成,dispatch的时候该函数会被自动执行
        dispatch(fetchAsyncBannerAction())
    }
}}

export default connect(mapStateToProps, mapDispatchToProps)(Home)

6. actionCreators.js

import * as actionTypes from './constants'

// 普通dispatch返回一个action对象
export function bannersAction(banners) {
  return {
    type: actionTypes.CHANGE_BANNERS,
    banners
  }
}

// 异步请求返回一个函数
export function fetchAsyncBannerAction() {
    // 希望他返回一个函数
    return (dispatch, getState) => {
        console.log('dispatch的时候该函数会自动执行')
        // 发送异步请求
        axios.get("xxxxxxxx").then((res) => {
          const banners = res.data.list
          dispatch(bannersAction(banners))
        })
    }
}