Redux - Basic use of Redux in React functional components

insert image description here

1. Introduction

Redux is a state container for JavaScript applications, providing predictable state management.

Its main methods are as follows:

insert image description here
The important methods are dispatch(分发action), getState(获取state), subscribe(监听state的变化), which will be introduced below, and the other two can be ignored;


So when to use Redux?

When encountering the following problems, it is recommended to start using Redux:

  1. You have a lot of data that changes over time
  2. You want the state to have a single source of truth
  3. You find it unmaintainable to manage all state in top-level components

Second, install

What I installed here is "redux": "^4.2.1"the version;

npm install redux --save

store文件夹New and under the src directory of the project index.js,reducer.js; as follows:

insert image description here

Three, the three core concepts Store, Action, Reducer

3.1 Store

Store: where data is stored. It is best to have only one Store for the entire application.

createStore(): Used to generate Store. Receives a Reducer as its argument.

index.js

/**
 * 引入createStore 专门创建最为核心的store对象
 * 目前createStore已经弃用,所以我们要引用legacy_createStore 
 */

iimport {
    
     legacy_createStore } from "redux";
import reducer from './reducer.ts'

// 创建数据仓库 引入reducer函数进行对数据的处理
const store = legacy_createStore(reducer)

export default store

3.2 Reducer

The essence of reduce is a function, which is used to initialize state and process state.

The reduce function receives two parameters, the first parameter is the initial value of the state, the second parameter is an action object, the first attribute in the object is the typename of the function, and the second attribute is the value passed in , for subsequent state changes;

reducer.ts


// 约束类型
interface Eula {
    
    
  name: string;
  age: number;
}
// 定义数据
const defaultState: Eula = {
    
    
  name: "Eula",
  age: 18
};

// reducer 函数 用于更改数据
let reducer = (preState = defaultState, action: {
     
      type: string; data: number }) => {
    
    
  // action解构出来
  let {
    
     type, data } = action;

  // 第一种写法 每个分支使用return进行返回
  // switch (type) {
    
    
  //   case "update_age":
  //     preState.age = data;
  //     return preState;
  //   case "add_age":
  //     preState.age++;
  //     return preState;
  //   case "del_age":
  //     preState.age--;
  //     return preState;
  //   default:
  //     return preState; // 初始化时
  // }

  // 第二种写法 break 与最终的return返回结果
  switch (type) {
    
    
    case "update_age":
      preState.age = data;
      break;
    case "add_age":
      preState.age++;
      break;
    case "del_age":
      preState.age--;
      break;
    default:
      preState; // 初始化时
  }
  return preState;  // 此处 一定要使用return进行返回最终改变的值
};

export default reducer;

Note: When the Store is loaded for the first time, it will automatically call the Reducer once to initialize the state. At this time, the state is undefined, and the type in the action object is @@redux/INITxxx. Manual calls store.dispatch()will also trigger the automatic execution of the Reducer.

3.3 Action

Action is an ordinary JS object, which is used to describe the data type and content to be updated. The type attribute is required, indicating the name of the Action, and other attributes can be set freely.

redux.tsx

// 引入store
import store from "../../../store/index";
// 更改数据时调用
store.dispatch({
    
     type: "update_age", data: 100 });

store.dispatch(): All data changes must be updated by dispatching Actions. Accepts an Action object as a parameter and sends it out.

Fourth, start using functional components

redux.tsx

import React, {
    
     useState } from "react";
//  1,引入store
import store from "../../../store/index";

// 渲染数据
const myList:[] = [];

const Redux: React.FC = () => {
    
    
  let [list, setList] = useState(myList);
  console.log("store:", store);

  // 监听数据的变化
  const unsubscribe = store.subscribe(() => {
    
    
    console.log("订阅数据的变化", store.getState());
    // 此处用来触发视图的更新
    setList([]);
  });

  // 改变store中的数据
  const update = () => {
    
    
    store.dispatch({
    
     type: "update_age", data: 100 });
  };
  const add = () => {
    
    
    store.dispatch({
    
     type: "add_age" });
  };
  const del = () => {
    
    
    store.dispatch({
    
     type: "del_age" });
  };

  // 此处才是真正渲染的页面
  return (
    <div className="redux">
      <h3>redux演示</h3>
      <button onClick={
    
    update}>更改store的数据+100</button>
      <button onClick={
    
    add}>更改store的数据++</button>
      <button onClick={
    
    del}>更改store的数据--</button>
      <p>store的num数据:{
    
    store.getState().age}</p>
    </div>
  );
};
export default Redux;

Renderings:

insert image description here

The above component is a simple case demonstration, which defines three click events, click the first button state.age+100, click the second button each time state.age+1, and click the third button age to decrease by one each time; the following will introduce several key contents in detail :

4.1, introduce store

Bring in first, there is nothing to say about this;

import store from "../../../store/index";

4.1,store.getState() method

getState()The method is one of the methods under the redux instance, and the first screenshot above has been printed out through the store instance;

getState()The function is to obtain the state running in redux in the current state; that is to say, to obtain the latest data in the store;

   <p>store的num数据:{
    
    store.getState().age}</p>

4.3,store.dispatch() method

dispatch()is the only behavior that can modify state data. Through distribution action (actually an object), the new state is calculated with the action and its payload passed in by the dispatch function, and updated to the closure data, thus realizing the update of the state;

As follows:
reducer.tsx

  // 改变store中的数据
  const update = () => {
    
    
    store.dispatch({
    
     type: "update_age", data: 100 });
  };
  const add = () => {
    
    
    store.dispatch({
    
     type: "add_age" });
  };
  const del = () => {
    
    
    store.dispatch({
    
     type: "del_age" });
  };

switch caseThe above code will correspond to the judgment of the following expression typeone by one, and is used to update the state;

reducer.ts

let reducer = (preState = defaultState, action: {
     
      type: string; data: number }) => {
    
    
  let {
    
     type, data } = action;
  
  // 第一种写法 每个分支使用return进行返回
  // switch (type) {
    
    
  //   case "update_age":
  //     preState.age = data;
  //     return preState;
  //   case "add_age":
  //     preState.age++;
  //     return preState;
  //   case "del_age":
  //     preState.age--;
  //     return preState;
  //   default:
  //     return preState; // 初始化时
  // }

  // 第二种写法 break 与最终的return返回结果
  switch (type) {
    
    
    case "update_age":
      preState.age = data;
      break;
    case "add_age":
      preState.age++;
      break;
    case "del_age":
      preState.age--;
      break;
    default:
      preState; // 初始化时
  }
  return preState;  // 此处 一定要使用return进行返回最终改变的值
};

The above two writing methods are the same; compare;

4.4,store.subscribe() method

subscribeAs long as the state data in the store changes, the function will trigger subscribethe method, which is equivalent to registering a listener; monitor the data changes in the store;

From the perspective of react, the store of redux is isolated. We need a bridge to update the logic of the UI layer while the data layer is updated. At this time, the last method in the store, the subscribe method, comes in handy.

Note: setList([]): is a method to actively trigger the update of the react view, otherwise the data in the store changes, but the view does not re-render.

import React, {
    
     useState } from "react";
const Redux: React.FC = () => {
    
     
  let [list, setList] = useState(myList);
// 监听数据的变化
  const unsubscribe = store.subscribe(() => {
    
    
    console.log("订阅数据的变化", store.getState());
    // 此处用来触发视图的更新
    setList([]);
  });
}

subscribeIt also returns an unsubscribe function. When we no longer want to subscribe to this listener, call it unsubscribe(), and the corresponding function will be removed from the listener queue.

unsubscrib() // 不再监听

Five, the three principles of Redux

  1. Single data source: The State of the entire application is stored in an object tree, and this object tree is only stored in one Store. A single data source can make the state of the entire application easy to maintain, modify, and track.
  2. State is read-only: the only way to modify State is to trigger Action, do not try to modify State in any other way. This ensures that all modifications are processed centrally and executed in strict order.
  3. Use pure functions to perform modifications: connect the old State and Action through a Reducer, and return a new State. All Reducers should be pure functions, without any side effects.

End:


[redux Chinese website] : https://cn.redux.js.org/

Guess you like

Origin blog.csdn.net/qq_43886365/article/details/132212256