← 返回首页
React基础教程(二十一)
发表时间:2022-07-05 16:54:05
react-redux

Redux 一般和 React 这类框架搭配使用,为了方便与 React 集成,Redux 官方提供了一个 react-redux 绑定库。

1.react-redux简介

react-redux 将组件划分为容器组件,UI组件和其他组件。

react-redux连接react和redux。能够使组件从 Redux store 中很方便的读取数据,并且向 store 中分发 actions 来更新数据。react-redux的两个核心概念:Provider和connect。

1).Provider Provider接收store作为props,然后通过context向下传递,这样react中任何组件都可以通过 context 获取到store。

2).connect

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

参数名 类型 说明
mapStateToProps(state, ownProps) Function 这个函数允许我们将store中的数据作为props绑定到组件上,state:redux中的,store, ownProps:自己的props
mapDispatchToProps(dispatch, ownProps) Function 将action作为props绑定到我们自己的函数中,dispatch:就是 store.dispatch(),ownProps:自己的props
mergeProps(stateProps, dispatchProps, ownProps) Function 不管是stateProps还是 dispatchProps,都需要和 ownProps merge 之后才会被赋给我们的组件,通常情况下,可以不传这个参数,connect就会使用Object.assign替代该方法
options Object 可以定制 connector 的行为

实例:

项目结构图如下:

package.json

"devDependencies": {
    "@babel/core": "^7.18.5",
    "@babel/plugin-transform-runtime": "^7.18.5",
    "@babel/preset-env": "^7.18.2",
    "@babel/preset-react": "^7.17.12",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "css-minimizer-webpack-plugin": "^4.0.0",
    "html-webpack-plugin": "^5.5.0",
    "mini-css-extract-plugin": "^2.6.1",
    "sass": "^1.52.3",
    "sass-loader": "^13.0.0",
    "style-loader": "^3.3.1",
    "terser-webpack-plugin": "^5.3.3",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.2",
    "webpack-merge": "^5.8.0"
  },
  "dependencies": {
    "@babel/runtime": "^7.18.3",
    "react": "^16.8.0",
    "react-dom": "^16.8.0",
    "react-router-dom": "^5.2.1",
    "redux": "^4.2.0",
    "redux-thunk": "^2.4.0",
    "axios": "^0.27.2",
    "react-redux": "^5.1.2"
  }

store/reduxmap.js

//提供state数据的映射
function mapStateToProps(state){
    return {
        i: state.i
    }
}

//提供操作dispatch的函数映射
function mapDispatchToProps(dispatch) {
    return {
        add(){
            let action = {
                type: 'add_i',
                i: this.props.i + 1
            }
            dispatch(action)
        }
    }
}

const mapFunction = {
    mapStateToProps,
    mapDispatchToProps
}

export default mapFunction

store/reducer.js

let defaultState = {
    i: 0
}

let reducer = (state = defaultState, action) => {

    if(action.type === 'add_i'){
        let tempState = JSON.parse(JSON.stringify(state))
        tempState.i = action.i
        return tempState
    }
    return state
}

export default reducer

store/index.js

import {legacy_createStore as createStore} from 'redux'
import reducer from './reducer'

let store = createStore(reducer)

export default store

Son.js

import React, { Component } from 'react'
import {connect} from 'react-redux'
import map from './store/reduxmap'

class Son extends Component {
    render() {
        return (
            <div>
                <h3>Son.js</h3>
                <div>
                    {this.props.i}
                    <button onClick={this.props.add.bind(this)}>+</button>
                </div>
            </div>
        )
    }
}
export default connect(map.mapStateToProps,map.mapDispatchToProps)(Son)

App.js

import React, { Component } from 'react'
import Son from './Son'
import {connect} from 'react-redux'
import map from './store/reduxmap'

class App extends Component {
    render() {
        return (
            <div>
                <h3>App.js</h3>

                <div>
                    {this.props.i}
                    <button onClick={this.props.add.bind(this)}>+</button>
                </div>
                <hr/>
                <Son/>
            </div>
        )
    }
}
export default connect(map.mapStateToProps,map.mapDispatchToProps)(App)

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'
import {Provider} from 'react-redux'
import store from './store'

const APP = (
    <Provider store={store}>
        <App></App>
    </Provider>
);

ReactDOM.render(APP, document.getElementById('root'));

运行效果: