场景
我遇到的问题是这样的:
维护一个state,类型是文件树类的实例,如下:
import { Node, Path } from './type';
export interface IFileeTree {
tree: Node;
currentNode: Node; // 当前节点
paths: Path; // 当前文件路径
isBackValid: boolean;
goBack: () => void;
intoFile: (target: Node) => void;
}
class FileTree implements IFileeTree {
public tree;
public currentNode;
public paths: Path;
constructor(tree: Node) {
this.tree = tree;
this.currentNode = tree;
this.paths = [tree];
}
// 进入文件夹或文件
public intoFile = (target: Node) => {
this.currentNode = target;
this.paths.push(target);
};
// 返回上一层
public goBack = () => {
if (!this.isBackValid) {
return;
}
const { paths } = this;
this.paths.pop();
this.currentNode = paths[paths.length - 1];
};
// 当前路径是否可返回上一层
get isBackValid() {
return this.paths.length > 1;
}
}
export default FileTree;
可以看到cur指针在实例中已经维护好了,在react组件中只需把tree绑定到state上就ok了。但我在展示层调用类上的方法,改变了cur指针,但是由于实例没变,引用没变,state就没有变化,所以不会render。但是我实例内部的cur指针确实是变了,react diff没查出来,但我不想再用一个state和树上的某些属性绑定,所以只能自己手动强行渲染。
解决方法
函数组件没有直接能用的hook,自己创建一个无意义state,仅用来用作强制渲染。
const [ignored, forceUpdate] = useReducer((x) => x + 1, 0); // mimic forceupdate
比如再在组件内部调用
const goBack = () => {
tree?.goBack();
forceUpdate();
};
状态更新,所以重新render了。