首页 > 解决方案 > 反应中的多个参考

问题描述

我有一个容器,它应该引用它的一些子组件:

const Container = () => {
  const blocks: HTMLDivElement[] = [];

  return (
    <div>
      <Navigation currentBlock={currentBlock} blocks={blocks} />
      <div ref={(ref) => ref && blocks.push(ref)}>
        // ...
      </div>
      <div ref={(ref) => ref && blocks.push(ref)}>
        // ...
      </div>
      <div ref={(ref) => ref && blocks.push(ref)}>
        // ...
      </div>
      <div ref={(ref) => ref && blocks.push(ref)}>
        // ...
      </div>
    </div>
  );
};

但是,当我尝试渲染Navigation组件时,blocks变量是一个空数组。

我尝试使用钩子将blocks变量转换为引用:useRef

const Container = () => {
  const blocks = useRef<HTMLDivElement[]>([]);

  return (
    <div>
      <Navigation currentBlock={currentBlock} blocks={blocks.current} />
      <div ref={(ref) => ref && blocks.current.push(ref)}>
        // ...
      </div>
      <div ref={(ref) => ref && blocks.current.push(ref)}>
        // ...
      </div>
      <div ref={(ref) => ref && blocks.current.push(ref)}>
        // ...
      </div>
      <div ref={(ref) => ref && blocks.current.push(ref)}>
        // ...
      </div>
    </div>
  );
};

blocks在渲染时仍然是一个空数组,但之后它变成了我想要的有效引用数组。

有没有办法在Navigation不重新渲染的情况下更新组件Container

编辑:这是我的Navigation组件:

const Navigation = ({ currentBlock, blocks }: { currentBlock: number, blocks: MutableRefObject<HTMLDivElement[]>}) => {
  console.log(blocks.current);
  return (
    <nav>
      {blocks.current.map((_, idx) => (
        <NavigationLink key={idx} active={currentBlock === idx} />
      ))}
    </nav>
  );
}

在我的控制台中,我有这个输出:

截屏

Navigation组件不渲染任何NavigationLinks,就好像数组为空一样。

标签: javascriptreactjstypescript

解决方案


要存储参考,您应该使用useRef钩子。但是,您必须将 refs 传递给另一个组件,而不是使用 blocks.current,而只是使用块。这样可以确保导航组件使用的道具可以访问变异的属性,因为在分配参考时不会触发重新渲染

const Container = () => {
  const blocks = useRef<HTMLDivElement[]>([]);

  return (
    <div>
      <Navigation currentBlock={currentBlock} blocks={blocks} />
      <div ref={(ref) => ref && blocks.current.push(ref)}>
        // ...
      </div>
      <div ref={(ref) => ref && blocks.current.push(ref)}>
        // ...
      </div>
      <div ref={(ref) => ref && blocks.current.push(ref)}>
        // ...
      </div>
      <div ref={(ref) => ref && blocks.current.push(ref)}>
        // ...
      </div>
    </div>
  );
};

现在在 Navigation 组件中,您可以使用props.blocks.current


推荐阅读