浅析redux

241 阅读3分钟

浅析redux

安装

npm install --save redux

原理图

image-20220303132839702

解释:

redux采取一棵==对象树==进行状态的管理,该对象树中仅仅包括一个store来控制各种状态在组件间的流通,使得不同组件之间的状态流通变得容易。但是,store中的内容只能是只读的,修改store中的内容只能通过reducer来进行控制,控制的方法是保留preState,抛出修改过的state副本。

假设现在有3个组件(A,B,C),现在要求A组件控制B组件在C组件上的显示与否,那么整个过程应该是这样的:

  • A组件分发一个action(action是store数据中的唯一有效来源)交给store,因此有sotre.dispatch(action);
  • 对于C组件B组件需要在上面显示,因此C组件应该订阅状态=>store.subscribe()

redux中的三驾马车

store

store是用在存储redux中action的部件,需要强调的是一个redux应用只能有一个store,如果应用较为复杂则可以将它们组合起来放到store中。

对于store 有以下一些职能:

image-20220303140014568

import {createStore} from "redux"
const store=createStore(Reducer);//注意,图中store不能处理action,只能交给reducer,因此需要接收reducer参数
export default store;

//组件C根据状态进行改变
useEffect(()=>{
    store.subscribe(()=>{
	console.log("订阅");
	})
    return {
        console.log("销毁")
    }
},[]);

Reducers

reducer是处理action的函数,它接收两个参数即过去的状态preStateaction

const reducer=(preState,action)=>{
    ...
    
    return preState;
}

export default reducer;

Action

action是用来传递数据的有效载荷,可以理解为告诉reducer你接下来想做什么操作。Action 本质上是 JavaScript 普通对象。action 内==必须==使用一个字符串类型的 type 字段来表示将要执行的动作。多数情况下,type 会被定义成字符串常量。

/*
 * action 类型
 */

export const ADD_TODO = 'ADD_TODO';
export const TOGGLE_TODO = 'TOGGLE_TODO'
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'

/*
 * 其它的常量
 */

export const VisibilityFilters = {
  SHOW_ALL: 'SHOW_ALL',
  SHOW_COMPLETED: 'SHOW_COMPLETED',
  SHOW_ACTIVE: 'SHOW_ACTIVE'
}

/*
 * action 创建函数
 */

export function addTodo(text) {
  return { type: ADD_TODO, text }
}

export function toggleTodo(index) {
  return { type: TOGGLE_TODO, index }
}

export function setVisibilityFilter(filter) {
  return { type: SET_VISIBILITY_FILTER, filter }
}

过程总结

案例:组件A控制组件B在组件C上的显示

步骤:

  • 对于全局:

    • 需要创建store.js:store接收一个reducer用于存储状态,接收组件发送的信息action

    • 需要创建reducer,用于对store传递过来的action进行识别并处理state,reducer接收两个参数即preState和action,返回一个state,但是该state不能是在preState基础上进行修改,而应该在preState的副本基础上进行修改(这个可能与内部diff算法有关)

      •   //store.js
          
          import {createStore} from "redux"
          
          const reducer=(preState={isShow:false},action)=>{
              switch(action.type){
                      case:"TURNON"
                      	reture {isShow:true};
              		case:"TURNOFF"
              			return {isShow:false};
          			default:
          				return preState;
          			//需要注意,此处的reducer并不类似于setState的合并更新,因此对于复杂数据结构需要
          			//采取immutable或者{...preState,...newState}
              }
          }
          
          const store = createStore;
          export default store;
        
  • 对于组件A:

    • 组件A控制B在C上的显示,因此组件A应该dispatch一个action给reducer

    •   import React from 'react'
        import { useState,useEffect } from 'react'
        import store from "./Store/"
        
        export default function A(){
            const[State,setState]=useState();
            useEffect(()=>{
                store.dispatch({
                    type:"TURNON",
                    ...State
                })//action必须至少有一个type属性,但是可以携带其它的东西,如这里解构本地State
            },[State]);//设置只要更新就dispatch一个action
            
            return (
            	<div>
                ...
                </div>
            )
        }
      
  • 对于组件C:

    • 组件C只有获取store中的state这一个功能,redux中state不能修改,就算修改也是在reducer处理后的副本

    •   import React from 'react'
        import store from "./Store/"
        
        export default function C(){
            const [Show,setShow]=useEffect(true);//组件可以拥有自己的状态,不必把所有的状态存到store中
            //如果store中的状态是动态更新的,那么就要订阅它
            let STATE;
        	store.subscribe(()=>{
                STATE=store.getState();//返回一个对象,其中包括preState以及newState
            });//只要action被dispatch一次那么内部回调函数就会执行一次
            return(
            	<div>
                ...
                </div>
            )
        }