react+redux+react-redux项目应用


安装

npm install redux --save
npm install react-redux --save

文件路径

src

index.js(react初始化文件)
redux(redux文件夹)

index.js(redux统一出口文件)
assistant.js(redux的模块reducer统一输出文件)

index.js(redux统一模块文件)
**.js(redux模块文件)

src/index.js 初始化文件

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import * as serviceWorker from './serviceWorker'
import configureStore from './redux' // 引入redux

// React-Redux 提供组件,能够使你的整个app访问到Redux store中的数据:
import {Provider} from 'react-redux'

const store = configureStore()

ReactDOM.render(
  
    
  ,
  document.getElementById('root')
)

src/redux/modules/car.js (redux模块文件)

// 初始化state数据
export const initialState = {
  count: 0,
  title: '首页展示'
}

// 定义action常量
const actionType = {
  ADD_COUNT: 'ADD_COUNT' // 新增数量
}

// 定义action方法
export const carActions = {
  addCount(count) {
    return {
      type: actionType.ADD_COUNT,
      count
    }
  }
}

// 输出模块的reducer方法
export default function car(state = initialState, action = {}) {
  switch (action.type) {
    case actionType.ADD_COUNT:
      return {...state, ...{count: state.count + action.count}}
    default:
      return state
  }
}

src/redux/modules/index.js 把module里面除了index.js的文件都自动引入,并调用redux的combineReducers方法和所有的reducer合并且统一输出(redux统一模块文件)

import {combineReducers} from 'redux'

let moduleMethods = {}
;(function updateModules() {
  const requireModule = require.context('.', true, /^((?!index|\.unit\.).)*\.js$/)
  requireModule.keys().forEach((fileName) => {
    const moduleConfig = requireModule(fileName)
    const moduleName = (fileName.replace(/^\.\//, '').replace(/\.js/, ''))
    moduleMethods[moduleName] = moduleConfig.default || moduleConfig
  })
})()

// 自动引入模块中的js文件,并合并在reducer中
const reducers = combineReducers({
  ...moduleMethods
})

export default reducers

src/redux/index.js 注册一个store,并且订阅一个subscribe监听数据变化时进行打印,向页面中抛出一个store(redux统一出口文件)

import {createStore} from 'redux'
import reducers from './modules' // 获取所有的reducer

export default function configureStore(initialState) {
  // reducers: 当前的 state 树和要处理的;  action:initialState:初始时的 state
  const store = createStore(reducers, initialState)

  function listen() {
    // 订阅打印最新的redux
    console.warn('订阅打印最新的redux:', store.getState())
  }

  store.subscribe(listen)
  if (module.hot) {
    module.hot.accept('./modules', () => {
      const nextReducer = require('./modules')
      store.replaceReducer(nextReducer)
    })
  }
  return store
}

src/redux/assistant.js 统一混合数据,页面中可以按需引入,使用connect连接在全局中混入方法

import {bindActionCreators} from 'redux'
import {carActions} from './modules/car' // 购物车

const actionMethods = {
  carActions,
  shoppingActions
}

/*********单个引入state,action*********/


export function carState(state) {
  return state.car
}

export function carAction(dispatch) {
  return {
    ...bindActionCreators(carActions, dispatch)
  }
}

/**
 * 一个页面使用多模块数据
 * @param state
 * @param value -- string/array
 *value不传参时默认取所有的state合并到页面中, value可传模块字符串取单个模块的数值合并到页面数据
 * value传多个参数时可以数组的形式,可把多个模块的数据合并到页面中
 */
export function mapStateToProps(state, value = '') {
  let stateObj = {}
  Object.keys(state).forEach((name) => {
    stateObj = {...stateObj, ...state[name]}
  })
  switch (typeof value) {
  case 'string':
    stateObj = {}
    stateObj = value ? state[value] : stateObj
    break
  case 'object':
    if (Array.isArray(value)) {
      stateObj = {}
      value.forEach((item) => {
        stateObj = {...stateObj, ...state[item]}
      })
    }
    break
  default:
    break
  }
  return stateObj
}

/**
 * 一个页面使用多模块action
 * @param state
 * @param value -- string/array
 *value不传参时默认取所有的state合并到页面中, value可传模块字符串取单个模块的数值合并到页面数据 eg: mapDispatchToProps(dispatch, 'carActions')
 * value传多个参数时可以数组的形式,可把多个模块的数据合并到页面中 eg: mapDispatchToProps(dispatch, ['carActions', 'shoppingActions'])
 */
export function mapDispatchToProps(dispatch, action = '') {
  let actionObj = {}
  Object.keys(actionMethods).forEach((item) => {
    actionObj = {...actionObj, ...actionMethods[item]}
  })
  switch (typeof action) {
  case 'string':
    if (action) {
      actionObj = {...actionMethods[action]}
    }
    break
  case 'object':
    if (Array.isArray(action)) {
      actionObj = {}
      action.forEach(item => {
        actionObj = {...actionObj, ...actionMethods[item]}
      })
    }
    break
  default:
    break
  }
  return {
    ...bindActionCreators(actionObj, dispatch)
  }
}

src/app.js 页面中使用的案例

引入单模块案例

import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';
// React-Redux提供一个connect方法能够让你把组件和store连接起来。
import {connect} from 'react-redux'
import {carState, carAction} from './redux/assistant'

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  addCount(count) {
    this.props.addCount(count)
  }

  render() {
    return (
      
logo

Edit src/App.js and save to reload.

当前标题为:{this.props.shopTitle}

当前数量为{this.props.count}

Learn React
) } } export default connect(carState, carAction)(App)

引入多模块案例

import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';
import {connect} from 'react-redux'
import {mapDispatchToProps, mapStateToProps} from './redux/assistant'

function getState(state) {
// 传入多个模块文件名称
  return mapStateToProps(state, ['car', 'shopping'])
}

function getAction(dispatch) {
// 传入多个模块action
  return mapDispatchToProps(dispatch, ['carActions', 'shoppingActions'])
}

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  addCount(count) {
    this.props.addCount(count)
    // this.props.setShopTitle('测试多模块redux成功')
  }

  render() {
    return (
      
logo

Edit src/App.js and save to reload.

当前标题为:{this.props.shopTitle}

当前数量为{this.props.count}

Learn React
) } } export default connect(getState, getAction)(App)

redux文档
react-redux文档

你可能感兴趣的:(react+redux+react-redux项目应用)