美文网首页让前端飞Web前端之路前端开发
react-redux详细使用方法@郝晨光

react-redux详细使用方法@郝晨光

作者: 郝晨光 | 来源:发表于2019-07-03 09:02 被阅读54次

前言

这篇文章是之前我发表在CSDN上边的,最近搬到简书

文件目录

    *---store   // 存放redux,数据,以及action
    
    *---store子目录
        actions  // 存放action的文件夹
        reducers // 存放reducer的文件夹
        actionTypes.js // 存放所有的actionType
        index.js // store的入口文件

安装

   npm install redux react-redux -S
   cnpm install redux react-redux -S
   yarn add redux react-redux -S

使用

  • 先在index.js中引入react-redux定义的Provider组件,并包裹在App组件外部
 import React from 'react';
 import ReactDOM from 'react-dom';
 import { Provider } from 'react-redux';
 import App from './App';
 
 ReactDOM.render(
     <Provider>
         <App />
     </Provider>,
     document.getElementById('root')
 );
  • 接着在store目录下的index.js中创建一个store,并抛出
 import { createStore, combineReducers } from 'redux';
  // createStore方法是用来创建store的,combineReducers方法是用来合并多个reducer的
  
  // 创建根reducer,利用combineReducers合并多个reducer,此处还未定义reducer,所以暂空
  const rootReducer = combineReducers({
  
  })
  
  // 创建初始化的state,初始化为一个空对象即可,默认的数据建议都写在reducer上
  const initializeState = {}; // 定义初始化的state
  
  // 创建store,第一个参数是根reducer,第二个参数可以是初始化的state,也可以是别的,暂且不提
  const store = createStore(rootReducer,initializeState);
  
  // 抛出store
  export default store;  
  • 在src/index.js中引入store,并且在Provider组件上使用
  /**之前的代码**/
 import store from './store';
  
 ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
 );
  • 接着可以先定义数据,即定义reducer,在src/store/reducers目录下,新建reducer,例如countReducer.js
  // 定义初始化的数据,根据实际数据即可
  const initializeState = {
      count: 1
  }
        
 // 定义reducer,第一个参数为state,赋予默认值为上边定义的initializeState,
// 第二个参数为action,并return一个state  
 // 并且抛出这个countReducer
 export default function countReducer(state = initializeState,action) {
      return state;
 }
  • 在src/store/index.js中引入定义的countReducer,并合并到rootReducer中
 // 引入countReducer, 
 import countReducer from './reducers/countReducer';
       
 // 将countReducer合并到rootReducer上,并使用原有名称
 const rootReducer = combineReducers({
      countReducer
 })
       
 // 也可以给countReducer改名,如下,改名成为count
 const rootReducer = combineReducers({
         count: countReducer
 })
  • 接着只需要将组件改造一下,就可以使用reducer上边的数据了

  • 在src/APP.js中,或者是你需要使用store中数据的组件中,引入react-redux提供的connect方法

 import { connect } from 'react-redux';
  • 并且在抛出之前,定义获取数据的方法mapStateToProps

      // 定义方法mapStateToProps,参数为state,并且返回一个对象,对象内定义需要获取的store内的数据,
      // 由于是使用的countReducer中的数据,所以需要使用state.countReducer.属性名 
      function mapStateToProps(state) {
           return {
               count: state.countReducer.count
           } 
      }
    
  • 接着,在抛出的时候调用connect方法改造当前组件

// connect的第一个参数为数据,即mapStateToProps方法
// 接着在第二个括号内传入当前需要被改造的组件  
export default connect(mapStateToProps)(App);
  • 然后,我们在被改造的组件内就可以通过this.props.属性名获取store中的数据了,例如我在mapStateToProps方法中返回的是count数据,所以我在App组件中使用this.props.count即可
class App extends Component {
   render() {
       return (
           <div>
               {this.props.count}
           </div>
       );
    } 
}
  • 获取到数据之后,接着应该是修改仓库内的数据

  • 修改数据首先需要定义一个dispatch,在redux中,修改数据必须通过dispatch提交一个action来进行,在src/store/actions目录下新建countAction.js

  • 在countAction.js中定义addCount方法,并return一个对象,对象上有一个type属性,这个属性对应的是一个常量字符串,这个字符串定义在src/store/actionTypes.js中,主要是为了可以公共的管理,因为同一个常量需要在两个地方使用

 // countAction.js
 
 import { ADD_COUNT } from '../actionTypes'
 
 export function addCount() {
     return {
         type: ADD_COUNT
     }
 }
 
 // actionTypes.js
 
 export const ADD_COUNT = 'ADD_COUNT';
  • 接着在src/store/reducers/countReducer.js中,引入ADD_COUNT常量,并使用switch语句,或者if语句对action.type进行判断,当触发这个action的时候,让当前这个reducer的state.count加一

        import { ADD_COUNT } from '../actionTypes';
    
        export default function countReducer(state = initializeState,action) {
            switch (action.type) {
                case ADD_COUNT:
                    return { count: state.count + 1 };
                default:
                    return state;
            }
        }   
    
  • 紧接着,要在组件中使用这个addCount方法,提交这个dispatch,触发这个action

  • 在App.js或者是使用store的组件中,首先引入addCount方法,然后在mapStateToProps的下边,在定义一个mapActionToProps方法,接着在connect的第二个参数位置,传入这个方法即可

  • 在mapActionToProps方法中,第一个参数为dispatch,return一个对象,对象上定义方法
    方法名自定义即可,接着触发这个方法的时候,触发dispatch(),并传入引入的addCount()方法,需要加括号调用,因为只有调用才会返回一个对象,( 或者addCount直接是一个对象,而不是一个函数 )

      import { addCount } from './store/actions/countAction'
      
      /** 其余代码 **/
      
      /** mapStateToProps **/
      
      function mapActionToProps(dispatch) {
          return {
              addCount: () => dispatch(addCount())
          }
      }
      
      export default connect(mapStateToProps,mapActionToProps)(App);
    
  • 此时,可以在App组件内调用this.props.addCount()方法来修改store中的数据了

  • 当然,但凡是方法,都可以传参,

  • 首先在src/store/actions/countAction.js中定义一个新的方法,

  • 当然,这个方法用到的REDUCE_COUNT常量要定义在src/store/actionTypes.js中

      // src/store/actions/countAction.js
      export function reduceCount(num) {
          return {
              type: REDUCE_COUNT,
              num
          }
      }
    
      // src/store/actionTypes.js
      export const REDUCE_COUNT = 'REDUCE_COUNT';
    
  • 而且,在src/store/reducers/countReducer.js中,需要通过switch进行判断action,并执行操作

  • 由于我们在action中定义的对象的属性是num,所以在reducer中进行参数使用的时候,也是使用action.num

  // src/store/reducers/countReducer.js
  import { ADD_COUNT, REDUCE_COUNT } from '../actionTypes'
  
  export default function countReducer(state = initializeState,action) {
      switch (action.type) {
          case ADD_COUNT:
              return { count: state.count + 1 };
          // 新增   
          case REDUCE_COUNT:
              return { count: state.count - action.num };
          default:
              return state;
      }
  }
  • 在App.js中使用reduceCount方法
 import { addCount, reduceCount } from './store/actions/countAction';

 /** 其余代码 **/
 
 /** mapStateToProps **/
 
 function mapActionToProps(dispatch) {
     return {
         addCount: () => dispatch(addCount()),
         reduceCount: (num) => dispatch(reduceCount(num))
     }
 }
  • 接着在组件中直接调用this.props.reduceCount()方法,并传入一个参数即可

  • 最后,为了遵循react的规范,我们需要在给组件定义props的时候,规定props的类型

  • 首先在App.js或者使用store的组件中,引入prop-types

  • 然后在文件最末尾,抛出之前,定义所有的props的类型

import PropTypes from 'prop-types';
 /** 其余代码 **/
       
App.propTypes = {
   count: PropTypes.number.isRequired,
   addCount: PropTypes.func.isRequired,
    reduceCount: PropTypes.func.isRequired
}

最终代码

index.js

 import React from 'react';
 import ReactDOM from 'react-dom';
 import { Provider } from 'react-redux';
 import store from './store';
 import App from './App';
 
 ReactDOM.render(
     <Provider store={store}>
         <App />
     </Provider>,
     document.getElementById('root')
 );

App.js

 import React, {Component} from 'react';
 import { connect } from 'react-redux';
 import { addCount, reduceCount } from './store/actions/countAction';
 import PropTypes from 'prop-types';
 
 class App extends Component {
     render() {
         return (
             <div>
                 <button onClick={()=>this.props.addCount()}>加1</button>
                 {this.props.count}
                 <button onClick={()=>this.props.reduceCount(5)}>减5</button>
             </div>
         );
     }
 }
 
 function mapStateToProps(state) {
     return {
         count: state.countReducer.count
     }
 }
 
 function mapActionToProps(dispatch) {
     return {
         addCount: () => dispatch(addCount()),
         reduceCount: (num) => dispatch(reduceCount(num))
     }
 }
 
 App.propTypes = {
     count: PropTypes.number.isRequired,
     addCount: PropTypes.func.isRequired,
     reduceCount: PropTypes.func.isRequired
 }
 
 export default connect(mapStateToProps,mapActionToProps)(App);

store/index.js

 import { createStore, combineReducers } from 'redux';
 import countReducer from './reducers/countReducer';
 
 const rootReducer = combineReducers({
     countReducer
 })
 
 const initializeState = {}; // 定义初始化的state
 
 const store = createStore(rootReducer,initializeState);
 
 export default store;

store/actionTypes.js

 export const ADD_COUNT = 'ADD_COUNT';
 export const REDUCE_COUNT = 'REDUCE_COUNT';

store/reducers/countReducer.js

 import { ADD_COUNT, REDUCE_COUNT } from '../actionTypes'
 
 const initializeState = {
     count: 1
 }
 
 export default function countReducer(state = initializeState,action) {
     switch (action.type) {
         case ADD_COUNT:
             return { count: state.count + 1 };
         case REDUCE_COUNT:
             return { count: state.count - action.num };
         default:
             return state;
     }
 }

store/actions/countAction.js

 import { ADD_COUNT, REDUCE_COUNT } from '../actionTypes'
 
 export function addCount() {
     return {
         type: ADD_COUNT
     }
 }
 
 export function reduceCount(num) {
     return {
         type: REDUCE_COUNT,
         num
     }
 }

- 如果需要使用中间件的话

  • 在store/index.js中,引入applyMiddleware,并使用在createStore的第三个参数位置
  • 接着引入需要使用的中间件,比如redux-thunk
  • 定义一个数组,用来存放所有的中间件
  • 在applyMiddleware方法中展开该数组即可
 import { createStore, combineReducers, applyMiddleware } from 'redux';
 // 引入redux-thunk
 import thunk from 'redux-thunk';

 // 定义中间件的数组
 const middleware = [ thunk ]

 // 使用
 const store = createStore(rootReducer,initializeState,applyMiddleware(...middleware));

结言
感谢您的查阅,代码冗余或者有错误的地方望不吝赐教;菜鸟一枚,请多关照

相关文章

网友评论

    本文标题:react-redux详细使用方法@郝晨光

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