【React】函数组件强制渲染 模仿forceUpdate

诸葛立果
2023-12-01

场景

我遇到的问题是这样的:
维护一个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了。

 类似资料: