记录一下reack hook 中使用的状态管理方式

91 阅读2分钟

休了一段时间的假期回来公司里已经全面使用新版react了,学习了一下,大部分项目使用contex+reducer,但是这种方式会导致页面刷新问题,数据量大并且需要频繁刷新页面的时候页面就容易卡顿。网上找了一下也没找到什么好的方式,算了,手动管理吧,顺便在此记录一下管理方式。 首先,先看一个useState

const [state, setState] = useState();

想法比较简单,既然setState会更新组件,那就把setState存起来吧,批量更新。 首先先整一个Store,存储数据与更新数据的接口

class Store<T> {
  private callbacks: Array<any>=[];
  private state: T;
  constructor(initalValue:T) {
    this.state=initalValue
  }

  //发布,这个是store里的dispatch
  dispatch = (data: T) => {
    this.state = { ...this.state,...data };
    //收到数据的时候就更新一波setState,那么相应的组件也会更新啦啦啦
    for (let i = 0; i < this.callbacks.length; i++) {
      this.callbacks[i](this.state);
    }
  }
  // 订阅,将useState 返回的setState们存储在这里
  subscribe = (callback:any) => {
    this.callbacks.push(callback);
  }
  // 取消订阅,组件卸载的时候将监听去掉
  unsubscribe = (callback:any) => {
    var index = this.callbacks.indexOf(callback); 
    if (index > -1) { 
      this.callbacks.splice(index, 1);
    };
  }
  //获取状态,以备不时之需
  getState=()=>this.state
};

export default Store;

存储结构有了,那么怎么把setState存进callbacks队列里呢?

整一个自定义hooks

import { useEffect, useState } from "react";
import Store from "./store";
export type userInfo = {
  email: string,
  name: string
}
//新建一个store,存储相应的数据,参数是初始值
export const userInfoStore = new Store<userInfo>({name:'zhangsan',email:''});
export const dispatch=userInfoStore.dispatch
export const useUseInfo = ()=> {
	//这个useState的初始值就是当前store里的state,保证组件订阅的时候拿到的是最新的状态
  const [state, setState] = useState<userInfo>(userInfoStore.getState());
	//此处将setState放入订阅队列
  useEffect(() => {
    userInfoStore.subscribe(setState)
    return () => {
    //此处移出队列
      userInfoStore.unsubscribe(setState);
    };
  },[]);

  return state;
}

ok,自定义组件写完,下一步就是调用了


import { useUseInfo,dispatch } from '@/store/useUseInfo'


const Example: React.FC = () => {
  const userInfo = useUseInfo();
  const updateUser=()=>dispatch({name:"lisi"})
  return ( <div>{userInfo.name}<button onClick={updateUser}>update</button></div>)
}

ok,录完,一个自定义hook对应一个store,当需要用store里的state时就调用自定义hook,如果想更新store里面的值就通过dispatch发送数据,齐活。