美文网首页
react+redux+react-redux项目应用

react+redux+react-redux项目应用

作者: Rotary | 来源:发表于2019-12-09 11:38 被阅读0次

安装

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

const store = configureStore()

ReactDOM.render(
  <Provider store={store}>
    <App/>
  </Provider>,
  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 (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo"/>
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <p>当前标题为:{this.props.shopTitle}</p>
          <p>当前数量为{this.props.count}</p>
          <button onClick={() => this.addCount(5)}>点击增加数量</button>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
      </div>
    )
  }
}
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 (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo"/>
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <p>当前标题为:{this.props.shopTitle}</p>
          <p>当前数量为{this.props.count}</p>
          <button onClick={() => this.addCount(5)}>点击增加数量</button>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
      </div>
    )
  }
}

export default connect(getState, getAction)(App)

redux文档
react-redux文档

相关文章

  • react+redux+react-redux项目应用

    安装 npm install redux --savenpm install react-redux --save...

  • python学习第一篇

    项目与应用的关系 使用Django创建一个项目,同时也需要创建一个项目的应用。多个应用在一个项目内,同时多个项目可...

  • Django学习笔记(一)基本流程

    创建项目及应用 创建项目执行命令:django-admin startproject 项目名称 创建应用执行命令:...

  • OWX使用说明

    OWX使用说明 项目设置 应用设置 通过UCS添加具体项目添加项目信息 Name(应用名称) Applicatio...

  •  Watch开发学习 (二)

    向iOS应用中添加Watch应用 要向现有项目中添加Watch应用对象,请执行以下操作: 打开现有的iOS应用项目...

  • django自带后台管理配置

    创建项目 创建应用 安装应用 运行项目 访问后台主页 http://127.0.0.1:8000/admin 创建...

  • Django框架基础02-模型

    MVT图解 项目准备 创建项目 创建应用 更换python解释器:按需选择 安装应用 本地化 模板路径在应用同级目...

  • 大连滕泰科技学习笔记2020-05-29

    项目组六 maven项目应用maven项目的规范srcmainjavaresoucestestmainjavare...

  • 项目日常应用

    以下是日常项目中使用到的一些小应用: 持续更新中。。。。。。 1,关于HttpClient--BasicNameV...

  • JS项目应用

    前言 在实际项目里面,我们使用面向对象编程进行编程 在面向对象编程里面我们大致分为四个部分(个人分法) 开头、获取...

网友评论

      本文标题:react+redux+react-redux项目应用

      本文链接:https://www.haomeiwen.com/subject/kjjbgctx.html