美文网首页
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项目应用

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