Redux详解(一) 使用篇

567 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情 

Redux 核心概念

redux流程

view --> action --> reducer --> store --> view

img.png

完整步骤。

  1. component组件dispatch
// 创建 store 传参数reducer
var store = Redux.createStore(reducer);
store.dispatch(action)
  1. Store 接收 Action 并将 Action 分发给 Reducer
  2. reducer根据action的type写逻辑代码,然后将更改后的state返回给store,reducer函数返回什么store就存什么,订阅方法subscribe 中就接受什么
  3. 组件订阅变量的状态,走订阅方法

我们以加减count为例,接受使用方法

// 2. 创建reducer
/**
 * @params state : 对象{} store 里面的所有变量 此例子里面只有一个变量count { count: 0 } 所以要给state一个默认值
 * @params action: { type : '', payload: {}} action 有两个参数,type 和传参payload
 * 
 * */
function reducer(state = { count: 0 }, action){
    switch (action) {
        case 'increment':
            return {...state, count: count + action.payload.tick};
        default:
            return state
    }
    
}
// 1. 首先创建store
const store = Redux.createStore(reducer)

// 3. 创建action,
const inscrement5 = {type: 'increment', payload: { tick: 5}}
const decrement5 = {type: 'increment', payload: { tick: -5}} // 传参 -5相当于减去(decrement)tick的功能

// 4. dispatch 发送action
document.getElementById('plus').onclick = function () {
    store.dispatch(inscrement5);
}

document.getElementById('mimus').onclick = function () {
    store.dispatch(decrement5);
}

// 5. 订阅 store
store.subscribe(() => {
    // 获取store对象中存储的状态
    const{ count } =  store.getState()
    document.getElementById('count').innerHTML = count;
})

React中使用Redux

主要是react-redux库,让redux和react结合的更紧密。

Provider

正常情况的redux如上面例子一样,全部写在一起,若在正常项目几十上百文件中使用,首先要解决的就是store对象共享到所有文件中,于是就有了provider // index.js


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

connect

connect高阶组件,可以将store中的state里面的变量以props形式传递给component,同时props里面还有dispatch 会帮我们订阅store 当store中的变量值发生更改的时候 会帮助我们重新渲染组件

export default connect(mapStateToProps, mapDispatchToProps)(Counter);

//Counter.js组件

import React from 'react';
import { connect } from 'react-redux';

function Counter ({count, increment5, decrement5}) {
  return <div>
    <button onClick={increment5}>+</button>
    <span>{count}</span>
    <button onClick={decrement5}>-</button>
  </div>
}


const mapStateToProps = state => ({
  count: state.counter.count
});

/**
 *
 * connect 方法第二个参数 
   @return 返回对象,在mapDispatchToProps中定义的所有action在组件props里面都能直接获取到,
   相当于调用`props.increment5`等价于 dispatch({type: 'increment', payload: { tick: 5}})
 * */

const mapDispatchToProps = dispatch => ({
  increment5 () {
    dispatch({type: 'increment', payload: { tick: 5}})
  },
   decrease5 () {
    dispatch({type: 'increment', payload: { tick: -5}})
  }
})

export default connect(mapStateToProps, mapDispatchToProps)(Counter);

综上,mapStateToProps是讲store中参数在封装组件中props中, mapDispatchToProps 则是省略掉 dispatch({type: 'increment', payload: { tick: 5}})而是直接在props中调increment5就相当于调了dispatch

bindActionsCreators

主要作用是传入action对象{type: 'increment', payload: { tick: -5}}帮我们加上dispatch{type: 'increment', payload: { tick: -5}}调用

优化后

//count.action.js文件


export const increment = payload => ({type: INCREMENT, payload});
export const increment5 = payload => ({type: INCREMENT5, { tick: 5}});
export const decrement5 = payload => ({type: DECREMENT5, { tick: -5}});

//Counter.js组件

import React from 'react';
import { connect } from 'react-redux';
import * as couterActions from '../store/actions/counter.actions';

//...省略代码...

/**
 *
 * connect 方法第二个参数 
   @return 返回对象,在mapDispatchToProps中定义的所有action在组件props里面都能直接获取到,
   相当于调用`props.increment5`等价于 dispatch({type: 'increment', payload: { tick: 5}})
 * */

const mapDispatchToProps = dispatch => (couterActions, dispatch)

export default connect(mapStateToProps, mapDispatchToProps)(Counter);

combineReducers

将多个reducer合在一起

// root.reducer.js文件
export default combineReducers({
  counter: CounterReducer,
  modal: ModalReducer
})





import RootReducer from "./reducers/root.reducer";
// 创建store的时候传参更简洁
const store = createStore(RootReducer)