react中redux组件和react-redux组件详细说明

第一种方式:Redux之combineReducers(reducers)详解

reducers (Object): 一个对象,它的值(value) 对应不同的 reducer 函数,这些 reducer 函数后面会被合并成一个。

reducers/todos.js

export default function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([action.text])
  default:
    return state
  }
}

reducers/counter.js

export default function counter(state = 0, action) {
  switch (action.type) {
  case 'INCREMENT':
    return state + 1
  case 'DECREMENT':
    return state - 1
  default:
    return state
  }
}

reducers/index.js

import { combineReducers } from 'redux'
import todos from './todos'
import counter from './counter'

export default combineReducers({
  todos,
  counter
})

App.js

import { createStore } from 'redux'
import reducer from './reducers/index'

let store = createStore(reducer)
console.log(store.getState())
// {
//   counter: 0,
//   todos: []
// }

store.dispatch({
  type: 'ADD_TODO',
  text: 'Use Redux'
})
console.log(store.getState())
// {
//   counter: 0,
//   todos: [ 'Use Redux' ]
// }

第一步,我们知道reducer 就是一个函数,接收旧的 state 和 action,返回新的 state

第二步,我们来看combineReducers(reducers)方法,把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore。

原文来自:http://blog.csdn.net/woshizisezise/article/details/51142968

第二种方式:redux和react-redux的用法:

@1:redux方法-----createStore(reducer, [initState, enhancer])

  • 作用:创建一个Redux store来存放应用中所有的state,一个应用只能有个store。函数返回store对象。
  • 参数:      
  • reducer(Function):两个参数:state和action,返回一个state。 不要对参数state进行修改,需要返回一个新的对象。
  • initStatate:初始state。如果不为空,需要和reducer中处理的state结构一致
  • enhancer:一个中间件,如logger等。

@2:redux方法-----combineReducers(reducers)

combineReducers辅助函数的作用是,把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore。

@3:redux方法-----applyMiddleware(...middlewares)

比如:

@4:redux方法-----bindActionCreators(actionCreators,dispatch)

经过bindActionCreators处理的actions,直接调用函数而不需调用dispatch即可触发state的改变。

@5: Store

Store是用来维持应用所有state树的一个对象。改变state的唯一方法是store dispatch一个action。
Store不是类,而只是一个有几个方法的对象,可以采用createStore进行创建。

    • getState()
      返回应用当前的 state 树。它与 store 的最后一个 reducer 返回值相同。
    • dispatch(action)
      分发action,这是改变state的唯一方法。
    • subscribe(listener)
      添加一个变化监听器,每当 dispatch action 的时候就会执行,state 树中的一部分可能已经变化。你可以在回调函数里调用 getState() 来拿到当前 state。函数返回一个解绑的函数。

原文组件说明:http://blog.csdn.net/tangzhl/article/details/71056110

@@1:统筹mapStateToProps和mapDispatchToProps

export default connect(mapStateToProps, mapDispatchToProps)(OtherMsg)
// OtherMsg 是类名
// class OtherMsg extends React.Component { // 具体的内容}

 

登录保存登录状态信息

src/store/loginreducer.js

export default function login(state={}, action){
    switch (action.type){
        case 'LOGIN':
            localStorage.uuid = action.data.uid;
            localStorage.session = action.data.session;
            localStorage.username = action.data.username;
            localStorage.avatar = action.data.avatar;
            return action.data;
            //break;
        case 'LOGOUT':
            localStorage.removeItem('uuid');
            localStorage.removeItem('session');
            localStorage.removeItem('username');
            localStorage.removeItem('avatar');
            break;
            //return state +2
        default:
            //break;
            return state;
    }
}

src/store/store.js

import { createStore, combineReducers } from 'redux';
import login from './loginreducer';

let store = createStore(login)
export default store;

src/components/Login.js

import React, { Component } from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import axios from 'axios';
import qs from 'qs';
import store from '../store/store';
class App extends Component {
    constructor(props) {
       super(props)
       this.state = {
           username:'',
           password:'',
           login:{}
       }
   }
   componentDidMount(){
          //store.subscribe(() =>  this.setState({login:store.getState()['login']}));
           store.subscribe(() => {
            this.setState({login:store.getState()});
            console.log(store.getState())
        });
        
   }
    loginBtnClick=()=>{
      axios.post('/api.php?m=api&c=user&a=login',qs.stringify({username:self.state.username, password:self.state.password})).then(res=>{
          if(res.data.success === 1){
              store.dispatch({type:'LOGIN',data:res.data.data});
              //console.log(this.state.login)
              /*if(this.props.state !=undefined){
                  this.props.history.push({pathname:this.props.location.state.from.pathname});
              }else{
                  this.props.history.push({pathname:'/index'});
              }*/
              //alert('成功');
          }else{
              alert('手机号码或者密码错误');
              return false;
          }
      })
  }
  render() {
     console.log(this.props)
      return (
          <button type="submit" className="login_button" id="btn-submit" onClick={this.loginBtnClick}>立即登录</button>
      )
  }
}
const mapStateToProps = (state) => {
  return {login: state}
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {}
}

export default connect(mapStateToProps,mapDispatchToProps)(App)

本地效果为:D:\www\svn\project\react_abacus\src\components/Login.js

 

 

其中一个大例子:

src/store/home/action-type.js

// 保存表单数据
export const SAVEFORMDATA = 'SAVEFORMDATA';
// 保存图片
export const SAVEIMG = 'SAVEIMG';
// 清空数据
export const CLEARDATA = 'CLEARDATA';

 

src/store/home/reducer.js

import * as home from './action-type';

let defaultState = {
  orderSum: '', //金额
  name: '', //姓名
  phoneNo: '', //手机号
  imgpath: '', //图片地址
}
// 首页表单数据
export const formData = (state = defaultState , action = {}) => {
  switch(action.type){
    case home.SAVEFORMDATA:
      return {...state, ...{[action.datatype]: action.value}};
    case home.SAVEIMG:
      return {...state, ...{imgpath: action.path}};
    case home.CLEARDATA:
      return {...state, ...defaultState};
    default:
      return state;
  }
}

src/store/production/action-type.js

// 保存商品数据
export const GETPRODUCTION = 'GETPRODUCTION';
// 选择商品
export const TOGGLESELECT = 'TOGGLESELECT';
// 编辑商品
export const EDITPRODUCTION = 'EDITPRODUCTION';
// 清空选择
export const CLEARSELECTED = 'CLEARSELECTED';

src/store/production/reducer.js

import * as pro from './action-type';
import Immutable from 'immutable';

let defaultState = {
  /**
   * 商品数据
   * @type {Array}
   * example: [{
   *    product_id: 1, 商品ID 
   *    product_name: "PaiBot(2G/32G)", 商品名称
   *    product_price: 2999, 商品价格
   *    commission: 200, 佣金
   *    selectStatus: false, 是否选择
   *    selectNum: 0, 选择数量
   * }]
   */
  dataList: [],
}

export const proData = (state = defaultState, action) => {
  let imuDataList;
  let imuItem;
  switch(action.type){
    case pro.GETPRODUCTION: 
      return {...state, ...action}
    case pro.TOGGLESELECT:
      //避免引用类型数据,使用immutable进行数据转换 
      imuDataList = Immutable.List(state.dataList);
      imuItem = Immutable.Map(state.dataList[action.index]);
      imuItem = imuItem.set('selectStatus', !imuItem.get('selectStatus'));
      imuDataList = imuDataList.set(action.index, imuItem);
      // redux必须返回一个新的state
      return {...state, ...{dataList: imuDataList.toJS()}};
    case pro.EDITPRODUCTION:
      //避免引用类型数据,使用immutable进行数据转换 
      imuDataList = Immutable.List(state.dataList);
      imuItem = Immutable.Map(state.dataList[action.index]);
      imuItem = imuItem.set('selectNum', action.selectNum);
      imuDataList = imuDataList.set(action.index, imuItem);
      // redux必须返回一个新的state
      return {...state, ...{dataList: imuDataList.toJS()}};
    // 清空数据
    case pro.CLEARSELECTED:
      imuDataList = Immutable.fromJS(state.dataList);
      for (let i = 0; i < state.dataList.length; i++) {
        imuDataList = imuDataList.update(i, item => {
          item = item.set('selectStatus', false);
          item = item.set('selectNum', 0);
          return item
        })
      }
      return {...state, ...{dataList: imuDataList.toJS()}};
    default: 
      return state;
  }
}

src/store/store.js

import {createStore, combineReducers, applyMiddleware} from 'redux';
import * as home from './home/reducer';
import * as production from './production/reducer';
import thunk from 'redux-thunk';

let store = createStore(
  combineReducers({...home, ...production}),
  applyMiddleware(thunk)
);

export default store;

home.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import API from '@/api/api';
import envconfig from '@/envconfig/envconfig';
import { saveFormData, saveImg, clearData } from '@/store/home/action';
import { clearSelected } from '@/store/production/action';
import PublicHeader from '@/components/header/header';
import mixin,{ padStr } from '@/utils/mixin';
import './home.css';

@mixin({padStr})
class Home extends Component{
  static propTypes = {
    formData:PropTypes.object.isRequired,
    saveFormData:PropTypes.func.isRequired,
    saveImg:PropTypes.func.isRequired,
    clearData:PropTypes.func.isRequired,
    clearSelected:PropTypes.func.isRequired,
  }

  state={
    alertStatus:false, //弹框状态
    alertTip:'', //弹框提示文字
  }
  /**
   * 已选择的商品数据
   * @type {Array}
   */
  selectedProList=[];

  //初始化数据,获取已选择的商品
  initData = props =>{
    this.selectedProList=[];
    props.proData.dataList.forEach(item=>{
      if(item.selectStatus && item.selectNum){
         this.selectedProList.push(item);
      }
    })
  }

  componentWillMount(){
    this.initData(this.props)
  }
  render(){
    console.log(this.props)
     return(
         <main className="home-container">
           <PublicHeader title='首页' record />
           <p className="common-title">请录入您的信息</p>
           <form className="home-form">
               <div className="home-form-tiem">
                    <span>销售金额:</span>
                    <input type="text" placeholder="清输入订单金额" value={this.props.formData.orderSum} />
               </div>
           </form>
           我就偶尔
         </main>
      )
  }
}
export default connect(state =>({
  formData: state.formData,
  proData: state.proData,
}),{
  saveFormData,
  saveImg,
  clearData,
  clearSelected,
})(Home);

 

 

本地效果为:D:\www\svn\project\react_redux\src\store

 React+Redux使用异步Action实现加减    http://blog.csdn.net/mutong19890803/article/details/53781563

第二种方式:

第三种方式:

 

posted @ 2018-01-25 17:07  chenguiya  阅读(1301)  评论(0)    收藏  举报