休了一段时间的假期回来公司里已经全面使用新版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发送数据,齐活。