useEffect 似乎在渲染完成之前被触发

useEffect appears to be triggered before render completion

我有这个 React 组件,我试图在组件完成渲染后将焦点移到特定的 div。

我试过在我的浏览器中进行调试,但从未设置 containerRef。当我在显示为 if (containerRef.current) { 的行暂停执行时,我还可以看到该组件尚未呈现。而且该组件目前只渲染一次(在 Storybook 中传递硬编码数据,但也尝试在真实应用程序中模拟它,认为 Storybook 中的某些包装器组件可能会以某种方式触发钩子)。

有什么建议吗?

export function DuplicateSelect(props: DuplicateSelectProps) {
  const containerRef = useRef(null);

  useEffect(() => {
    if (containerRef.current) {
      containerRef.current.focus();
    }
  });

  return (
    <Overlay isOpen={true}>
      <div className="flex-center">
        <Card className="duplicate-select" elevation={1}>
          <div
            className="duplicate-select-options"
            tabIndex={0}
            ref={containerRef}
          >
            {props.results.map((result) => (
              <Item data={result} />
            ))}
          </div>
        </Card>
      </div>
    </Overlay>
  );
}

在 Codesandbox 中制作了一个原型并且工作正常:https://codesandbox.io/s/damp-dust-4xiv0

useEffect 挂钩添加第二个参数,以便在设置 ref 时触发它

useEffect(() => {
    if (containerRef.current) {
      containerRef.current.focus();
    }
 }, [containerRef.current]);

我正在使用 Blueprint.js 作为 UI 库,经过进一步调查,我发现问题是由于门户内的 <Overlay> 组件呈现。有一个禁用此行为的道具可以解决问题。似乎在使用门户网站时 refs 可能会中断?

export function DuplicateSelect(props: DuplicateSelectProps) {
  const containerRef = useRef(null);

  useEffect(() => {
    if (containerRef.current) {
      containerRef.current.focus();
    }
  });

  return (
    <Overlay isOpen={true} usePortal={false} >
      <div className="flex-center">
        <Card className="duplicate-select" elevation={1}>
          <div
            className="duplicate-select-options"
            tabIndex={0}
            ref={containerRef}
          >
            {props.results.map((result) => (
              <Item data={result} />
            ))}
          </div>
        </Card>
      </div>
    </Overlay>
  );
}