前后端知识库 前后端知识库
首页
    • JavaScript
    • React
    • Vue
  • Python
  • Sanic
  • Linux
  • Ansible
归档
GitHub (opens new window)
首页
    • JavaScript
    • React
    • Vue
  • Python
  • Sanic
  • Linux
  • Ansible
归档
GitHub (opens new window)
  • JavaScript

  • React

    • 脚手架
    • 组件
    • 组件通信
    • 事件和 ref
    • 生命周期
    • 组件渲染 —— 条件渲染(动态组件)
    • 状态管理器Redux
      • 安装
      • 创建仓库
      • 与 react 进行关联
      • connect
    • 路由Router
    • 表单
    • Webpack
  • Vue

  • frontend
  • React
devin
2023-09-07

状态管理器Redux

# Redux

React 不同与双向数据绑定框架,它是单向数据流,所以每次更新都得调用setState,所以在跨组件通信中会比较迂回。还有就是 React 没有逻辑分层,在开发过程中,逻辑分层是很重要的。

Redux 实现了跨组件通信和逻辑分层的好处,所以在 React 中使用 Redux 更配。

# Redux 简单实现

为了说明问题,先来一个公共对象实现跨组件通信。当然这个也是 flux 的实现原理。

# actions.js
export default {
  increment() {
    return {
      type: "+",
    };
  },
  decrement() {
    return {
      type: "-",
    };
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
# reducer
export default (state = 0, action) => {
  switch (action.type) {
    case "+":
      return state + 1;
    case "-":
      return state - 1;
    default:
      return state;
  }
};
1
2
3
4
5
6
7
8
9
10

# component

import React, { Component } from "react";
import { createStore } from "redux";
import Actions from "./actions";
import Reducer from "./reducer";

const store = createStore(Reducer);

export default class Component1 extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }
  increment = () => {
    store.dispatch(Actions.increment());
    this.setState({
      count: store.getState(),
    });
  };

  render() {
    return (
      <div>
        <h3>component-cp1-{this.state.count}</h3>
        <input type="button" value="increment" onClick={this.increment} />
      </div>
    );
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 小结——分层

  • Actions 层
    • 用户行为操作,由用户在 View 层触发 store.dispatch(Actions.increment());
    • 行为操作应该为一个 function且必须返回有type属性的对象
    • 每个方法都应该由store进行派发。
  • Reducer 层
    • 必须是一个纯函数(一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用)
    • 接受两个参数,第一个为state,另一个为action
    • return的结果可以用store.getState()来接收
  • Store 层
    • redux的一个方法,接受reducer,返回一个对象store
    • 对象store的方法dispath用于派发action
    • 通过dispath派发的action会触发reducer
  • View 层
    • 视图层,也就是组件
    • 通过getState()获取的值然后再setState便可以显示。

# 基础入门

一般用于复杂的组件之间通信数据,比如

  • 父传子(props)
  • 兄弟通信(redux/vuex)平行组件之间的通信
State(存放数据的地方)通信的数据都会存放在这里
Getter (获取需要通信的数据)
Mutation (修改交换的数据)
Action  (触发Mutation)
Module  (分开多个State仓库)
1
2
3
4
5

# 安装

安装redux的两个必须模块

cnpm install --save redux
npm install --save react-redux
1
2

# 创建仓库

 创建一个仓库,最终目的就是要生成一个store仓库,该仓库有一个state存放数据 还有一个action来触发state的更改

import { createStore } from "redux";
// react的写法
const store = createStore((state = 0, action) => {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
});
// vue的写法
const store = new Vuex.Store({
  state: {
    count: 0,
  },
  mutations: {
    increment(state) {
      state.count++;
    },
  },
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 与 react 进行关联

把<Provider>注入到根组件里面,把<Router>和<App />组件包含起来,把刚才上面生成的store注入到<Provider store={store}>组件里面,这个时候,整个 app 的都可以redux的状态管理

// 把上面配置好的store和react进行关联
import { Provider, connect } from "react-redux";
ReactDOM.render(
  <Provider store={store}>
    <Router>
      <App />
    </Router>
  </Provider>,
  document.getElementById("root")
);
1
2
3
4
5
6
7
8
9
10

# connect

把组件和store进行一次关联。就如果没有connect,这个仓库是没有任何人能访问的

import { connect } from "react-redux";
// 该组件如果想跟store进行连接就在导出的时候用
export default connect(
  (state) => {
    // 第一个函数把store里面的值注入到Wnav组件的`props`上面
    // 第一个函数是获取store的值

    // 和store的state产生关系
    console.log(state);
    return state;
  },
  (dispatch) => {
    // 第二个函数是触发store的值改变
    // 相当于vue(action,commit->mutation)
    // 你可以在此处定义多个函数,来去触发store里面的`dispatch`,从而改变`store`里面的值

    // 和store的action产生关系
    return {
      onIncreaseClick() {
        dispatch("increaseAction");
      },
    };
  }
)(Wnav);

// 不连接store的话
// export default Wnav
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
编辑 (opens new window)
上次更新: 2023/09/07, 15:09:00
组件渲染 —— 条件渲染(动态组件)
路由Router

← 组件渲染 —— 条件渲染(动态组件) 路由Router→

Theme by Vdoing | Copyright © 2023-2023 devin | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式