使用 react-redux 实现组件的状态管理和数据通信

1. 实现效果

使用 react-redux 实现组件的状态管理和数据通信_第1张图片

上面是Count组件,下面是Flag组件。

Count组件中,点击点击+1按钮,数值加一,点击清零按钮,数值清零,同时数值传递给Flag组件同步显示。

Flag组件中,点击login可以切换为true,点击logout切换为false,同时将状态传递给Count组件同步显示。

2. 安装依赖包

npm install react-redux redux redux-thunk redux-devtools-extension

3. 文件结构

使用 react-redux 实现组件的状态管理和数据通信_第2张图片

使用了redux,需要在UI组件外套一层容器组件。由于是父子关系,容器组件通过props向里层的UI组件传递参数,将容器组件放在containers文件夹下。

使用redux,需要单独创建redux文件夹,包括actions文件夹和reducers文件夹,还有向外暴露常量的constant.jsstore.js

4. 详细代码

1. Count 组件

(1)组件定义

通过class定义的是UI组件,向外暴露的是容器组件容器组件通过propsUI组件传递状态方法

// src/containers/Count/index.jsx
import React, {
      Component, Fragment } from 'react';
import {
      connect } from 'react-redux';
import {
      add, clear } from '../../redux/actions/count';

// UI组件
class Count extends Component {
     
    add = () => {
     
        // 通知redux
        this.props.add(1);
    };
    clear = () => {
     
        this.props.clear();
    };
    render() {
     
        return (
            <Fragment>
                <h2>当前求和为:{
     this.props.count}</h2>
                <h3>当前Flag:{
     this.props.flag ? 'true' : 'false'}</h3>
                <button onClick={
     this.add}>点击+1</button>
                <button onClick={
     this.clear}>清零</button>
            </Fragment>
        );
    }
}

// 暴露容器组件
export default connect(
    // 1.状态
    state => ({
      count: state.sum, flag: state.flagState }),
    // 2.方法
    {
      add, clear }
)(Count);

(2)创建action

该文件用于创建action对象。

// src/redux/actions/count.js
// 为Count组件创建action对象

// 引入常量
import {
      ADD, CLEAR } from '../constant';

// 创建加一action对象的函数
export const add = data => ({
     
    type: ADD,
    data,
});

// 创建清零action对象的函数
export const clear = data => ({
     
    type: CLEAR,
    data,
});

(3)reducer

该文件用于判断type的类型,加工数据。

// src/redux/reducers/count.js
// 为Count组件创建一个reducer
// reducer接收两个参数:之前状态的preState,动作对象action

import {
      ADD, CLEAR } from '../constant.js';

// 设定初始状态
const initState = 0;

export default function addReducer(preState = initState, action) {
     
    // 从action中获取type和data
    const {
      type, data } = action;
    // 根据type决定如何加工数据
    switch (type) {
     
        case ADD:
            return preState + data;
        case CLEAR:
            return 0;
        // 初始化动作
        default:
            return preState;
    }
}

2. Flag 组件

(1)组件定义

// src/containers/Flag/index.jsx
import React, {
      Component, Fragment } from 'react';
import {
      connect } from 'react-redux';
import {
      login, logout } from '../../redux/actions/flag';

class Flag extends Component {
     
    login = () => {
     
        this.props.login();
    };
    logout = () => {
     
        this.props.logout();
    };

    render() {
     
        return (
            <Fragment>
                <h2>当前Flag:{
     this.props.flag ? 'true' : 'false'}</h2>
                <h3>当前求和为:{
     this.props.count}</h3>
                <button onClick={
     this.login}>login</button>
                <button onClick={
     this.logout}>logout</button>
            </Fragment>
        );
    }
}

export default connect(state => ({
      flag: state.flagState, count: state.sum }), {
      login, logout })(
    Flag
);

(2)创建action

// src/redux/actions/flag.js
// 为Flag组件创建action对象

// 引入常量
import {
      LOGIN, LOGOUT } from '../constant';

// 创建加一action对象的函数
export const login = data => ({
     
    type: LOGIN,
    data,
});

// 创建加一action对象的函数
export const logout = data => ({
     
    type: LOGOUT,
    data,
});

(3)reducer

// src/redux/reducers/flag.js
//  reducer接收两个参数:之前状态的preState,动作对象action

import {
      LOGIN, LOGOUT } from '../constant.js';

// 设定初始状态
const initState = false;

export default function addReducer(preState = initState, action) {
     
    const {
      type } = action;
    switch (type) {
     
        case LOGIN:
            return true;
        case LOGOUT:
            return false;
        default:
            return preState;
    }
}

3. 汇总所有 reducer

所有的组件的reducer要汇总到一个文件中,并向外暴露redux中存放的状态对象

// src/redux/reducers/index.js
// 汇总所有的reducer

import {
      combineReducers } from 'redux';

import sum from './count';
import flagState from './flag';

export default combineReducers({
     
    sum,
    flagState,
});

4. 常量文件

// src/redux/constant.js
export const LOGIN = 'login';
export const LOGOUT = 'logout';

export const ADD = 'add';
export const CLEAR = 'clear';

5. store

引入汇总后的rudecer,暴露store

// src/redux/store.js
// 整个文档只有一个store对象

import {
      createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import allRudecers from './reducers';
import {
      composeWithDevTools } from 'redux-devtools-extension';

// 暴露store
export default createStore(allRudecers, composeWithDevTools(applyMiddleware(thunk)));

6. 项目入口文件 index.js

引入store,并将包裹,这样下所有的组件都能接收到store了。

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

ReactDOM.render(
    // Provider包裹App,目的:让App所有的后代容器组件都能接收到store
    <Provider store={
     store}>
        <App />
    </Provider>,
    document.getElementById('root')
);

欢迎在我的博客上访问:
https://lzxjack.top/

你可能感兴趣的:(前端整理,React,React,redux,前端)