React 之 react-redux

99 阅读3分钟

theme: fancy

上篇文章简单讲了 redux ,本文讲解redux 搭配 React 。

需要先安装

安装 React Redux

npm install --save react-redux

常用使用方法

import {Provider, connect, combineReducers, bindActionCreators} from "react-redux";

  • Provider 提供者:挂载传递store, 类比react context
  • connect connect 连接:映射 store, dispatch 到组件,connect(mapStoreToProps, mapDispatchToProps )(组件component)
  • combineReducers 组合 多个 Reducer
  • bindActionCreators 作用是将单个或多个ActionCreator转化为dispatch(action)的函数集合形式

1. 定义 action

  • 新建文件 actions.js
function add() {
    return {type: "ADD"};
}

function minus() {
    return {type: "MINUS"}
}

const actions = {add, minus};

export default actions;

2. 定义 Reducer

  • 新建文件 reducer.js
import {
  add,
  minus
} from './actions'
// 定义常量
// export const ADD = "ADD";
// export const MINUS = "MINUS";

import {
  add,
  minus
} from './actions'


// 首次初始化 count 为 0 
function reducer(state={count: 0}, action) {
    console.log('reducer -- action', action , state);

    switch (action.type){
        case add.type:
            return  {count: state.count + 1};
            break;
        case minus.type:
            return {count: state.count - 1};
            break;
        default:
            return state;

    }
}

3. 定义 Store

  • 新建文件 Store.js
import {createStore, combineReducers} from 'redux';
import reducer from './reducer';
import reducer2 from './reducer2';
// 如有多个 reducer, 则都引入,用 combineReducers 将多个 reducer 合并成为一个


const todoApp = combineReducers({ reducer, reducer2 ... })

// 创建一个 Redux [store] 来以存放应用中所有的 state。
const store = createStore(todoApp);
export default store;


4. 传入 Store

- 所有容器组件都可以访问 Redux store,所以可以手动监听它。一种方式是把它以 props 的形式传入到所有容器组件中。但这太麻烦了,因为必须要用 `store` 把展示组件包裹一层,仅仅是因为恰好在组件树中渲染了一个容器组件。

- 建议的方式是使用指定的 React Redux 组件 [`<Provider>`](https://github.com/reactjs/react-redux/blob/master/docs/api.md#provider-store) 来 [魔法般的](https://facebook.github.io/react/docs/context.html) 让所有容器组件都可以访问 store,而不必显示地传递它。只需要在渲染根组件时使用即可。
  • 新建入口文件 index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';


import {Provider} from "react-redux";
import store from "./store";

ReactDOM.render(
    <Provider store={store}>
        <App/>
    </Provider>,
    document.getElementById('root')
);


App.js 文件

import Counter from "./counter";

// 容器组件
function App() {
    return (
        <div className="App">
            <Counter/>
        </div>
    );
}

export default App;

5. 使用 connect() 创建 Counter

Counter 组件中

import React from "react";
import {connect} from "react-redux";
import actions from "./actions";

class Counter extends React.Component {
    render() {
        console.log('Counter,this.props', this.props)
        return (
            <>
                <p>Count:{this.props.count}</p>
                <br/>
                <button onClick={this.props.dispatch(actions.add)}>Count++</button>
                &nbsp;&nbsp;&nbsp;
                <button onClick={this.props.dispatch(actions.minus)}>Count--</button>
            </>
        );
    }
}


// 将store中的state和需要store派发的action绑定到组件中
export default connect()(Counter);

或者

import React from "react";
import {connect} from "react-redux";
import actions from "./actions";

class Counter extends React.Component {
    render() {
        console.log('Counter,this.props', this.props)
        return (
            <>
                <p>Count:{this.props.count}</p>
                <br/>
                <button onClick={this.props.add}>Count++</button>
                &nbsp;&nbsp;&nbsp;
                <button onClick={this.props.minus}>Count--</button>


                {/* 这样的时候需要吧mapDispatchToProps去掉,否则把  dispatch map 丢了 */}
                {/* <br/>
                <button onClick={ ()=> this.props.dispatch({type: 'ADD'})}>Count++</button>
                &nbsp;&nbsp;&nbsp;
                <button onClick={ ()=> this.props.dispatch(actions.add)}>Count++</button>
                &nbsp;&nbsp;&nbsp;
                <button onClick={ ()=> this.props.dispatch({type: 'MINUS'})}>Count--</button> 
                <button onClick={ ()=> this.props.dispatch(actions.minus)}>Count--</button>*/}
            </>
        );
    }
}

// 函数,这个函数允许我们将 `store` 中的数据作为 `props` 绑定到组件上。
// state 是store 中的数据 ,  ownProps 是组件的 props 数据
const mapStateToProps = (state, ownProps) => {  
    return {
        count: state.count
    }
}

//对象:保存的action
const mapDispatchToProps = (dispatch, ownProps) => { 
    add: ()=>{ 
        dispatch(actions.add)
    },
    minus: ()=>{
        dispatch(actions.minus)
    },
}

// 将store中的state和需要store派发的action绑定到组件中
export default connect(mapStateToProps, mapDispatchToProps)(Counter);


connect() 接收四个参数,它们分别是 mapStateToProps , mapDispatchToProps, mergeProps 和 options 。

注意 mapStateToPropsmapDispatchToProps的使用

mapStateToProps

这个函数允许我们将 store 中的数据作为 props 绑定到组件上。


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


mapDispatchToProps


const mapDispatchToProps = (dispatch, ownProps) => { 
    return {
        add: ()=>{ 
            dispatch(actions.add)
        },
        minus: ()=>{
            dispatch(actions.minus)
        }
    }
}

1.previder 提供者:挂载传递store, 类比react context 2.connect 连接:映射 store, dispatch 到组件 。connect(mapStoreToProps, mapDispatchToProps )(组件component)

其他状态管理库

mobx

recoil

dva