react状态管理器(分模块)之redux和redux + react-redux + reducer和redux + react-redux + reducer分模块 + 异步操作redux-thunk

1、回顾

cnpm i redux react-redux redux-thunk -S

store/index.js

src/index.js

src/views/home/index.jsx + UI.jsx

2、redux 分模块

2.1 分页面创建页面需要的状态,以首页为例

views/home/reducer.js

const reducer = (state = {
  bannerlist: [],
  prolist: []
}, action) => {
  const { type, data } = action;
  switch (type) {
    case 'CHANGE_BANNER_LIST':
      return { ...state, ...{ bannerlist: data } };
    case 'CHANGE_PRO_LIST':
      return { ...state, ...{ prolist: data } }  
    default:
      return state
  }
}

export default reducer;

views/kind/reducer.js + views/cart/reducer.js

2.2 创建仓库 store/index.js

import { createStore, combineReducers } from 'redux'

import home from '@/views/home/reducer';
import kind from '@/views/kind/reducer';
import cart from '@/views/cart/reducer';

// combineReducers 合并reducer
const reducer = combineReducers({
  home,
  kind,
  cart
})

const store = createStore(reducer);

export default store;

2.3 入口文件处兼容仓库的变化

import store from './store';
function render () {
  ReactDOM.render(
    <Router>
      <Switch>
        <Route path="/" component = { App } />
      </Switch>
    </Router>,
  document.getElementById('root')
  )
}

render()

store.subscribe(render)

2.4 页面组件使用仓库

// 触发状态改变
store.dispatch({type: '', data: ''})
// 获取状态
store.getState() // {home: {}, kind: {}, cart: {}}

3、redux + react-redux + reducer分模块

3.1 页面组件分为容器组件和UI组件 index.jsx + UI.jsx + reducer.js

  • index.jsx
import { connect } from 'react-redux';
import UI from './UI';

export default connect()(UI)
  • UI.jsx 就是各个页面 -- 以首页为例
import React, { Component } from 'react';
export default class extends Component {
  componentDidMount () {
  }
  render () {
    return (
      <div className="box">
        <header className = "header">首页</header>
        <div className = "content">
          首页
        </div>
      </div>
    )
  }
}
  • reducer.js 首页的状态
const reducer = (state = {
  bannerlist: [],
  prolist: []
}, action) => {
  const { type, data } = action;
  switch (type) {
    case 'CHANGE_BANNER_LIST':
      return { ...state, ...{ bannerlist: data } };
    case 'CHANGE_PRO_LIST':
      return { ...state, ...{ prolist: data } }  
    default:
      return state
  }
}

export default reducer;

3.2 store/index.js整合reducer

import { createStore, combineReducers } from 'redux'

import home from '@/views/home/reducer';
import kind from '@/views/kind/reducer';
import cart from '@/views/cart/reducer';

const reducer = combineReducers({
  home,
  kind,
  cart
})

const store = createStore(reducer);

export default store;

3.3 入口文件处处理 仓库

import store from './store';
import { Provider } from 'react-redux';
ReactDOM.render(
  <Provider store={ store }>
    <Router>
      <Switch>
        <Route path="/" component = { App } />
      </Switch>
    </Router>
  </Provider>,
document.getElementById('root')
)

3.4 容器组件获取状态

import { connect } from 'react-redux';
import UI from './UI';

// const mapStateToProps = ({ home: { bannerlist, prolist } }) => ({ bannerlist, prolist })

const mapStateToProps = (state) => {
  return {
    bannerlist: state.home.bannerlist,
    prolist: state.home.prolist
  }
}
export default connect(mapStateToProps)(UI)

3.5 容器组件提供UI组件需要的业务逻辑

import { getBannerlist, getProlist } from '@/utils/api';
const mapDispatchToProps = (dispatch) => {
  return {
    getBannerlist () {
      getBannerlist().then(data => { dispatch({ type: 'CHANGE_BANNER_LIST', data: data.data } ) })
    },
    getProlist () {
      getProlist().then(data => { dispatch({ type: 'CHANGE_PRO_LIST', data: data.data } ) })
    }
  }
}
export default connect(mapStateToProps, mapDispatchToProps)(UI)

3.6 UI组件使用状态和触发业务逻辑

import React, { Component } from 'react';
export default class extends Component {
  componentDidMount () {
    this.props.getBannerlist();
    this.props.getProlist();
  }
  render () {
    let { bannerlist, prolist } = this.props
    return (
      <div className="box">
        <header className = "header">首页</header>
        <div className = "content">
          首页
          { 
            bannerlist.map((item) => (
              <p key={ item.bannerid }> { item.img } </p>
            ))
          }
           { 
            prolist.map((item) => (
              <p key={ item.proid }> { item.proname } </p>
            ))
          }
        </div>
      </div>
    )
  }
}

4、redux + react-redux + reducer分模块 + 异步操作redux-thunk

目前异步操作在容器组件内部,需要把异步操作抽离出来 ---- actionCreator.js

以首页为例
i

4.1 仓库中引入异步操作的中间件 store/index.js

import { createStore, combineReducers, applyMiddleware } from 'redux'
import thunk from 'redux-thunk';//+++++

import home from '@/views/home/reducer';
import kind from '@/views/kind/reducer';
import cart from '@/vews/cart/reducer';

const reducer = combineReducers({
  home,
  kind,
  cart
})

const store = createStore(reducer, applyMiddleware(thunk));//+++++

export default store;

4.2 views/home/actionCreator.js

import { getBannerlist, getProlist } from '@/utils/api';

export default {
  getBannerlist (dispatch) {
    getBannerlist().then(data => {
      dispatch({
        type: 'CHANGE_BANNER_LIST',
        data: data.data
      })
    })
  },
  getProlist (dispatch) {
    getProlist().then(data => {
      dispatch({
        type: 'CHANGE_PRO_LIST',
        data: data.data
      })
    })
  }
}

4.3 容器组件处触发actionCreator

posted @ 2019-11-20 20:20  菜鸟小何  阅读(503)  评论(0编辑  收藏  举报