0

編集:この問題は、ForwardRef を Redux 接続と組み合わせて使用​​しようとしたために発生しました。解決策については、この投稿をご覧ください。

React.forwardRef を使用して、親コンポーネントの DOM 要素にアクセスしようとしています。問題は、最初のレンダリングの後でも ref.current が定義されないことです。

この親コンポーネントでは、子コンポーネントの 1 つから DOM 要素にアクセスしたいと考えています。

const MyFunctionComponent = () => {
  const bannerRef = useRef<HTMLDivElement>(null);

  let bannerIndent = useRef<string>();

  useEffect(() => {
    // bannerRef.current is ALWAYS null. Why?
    if (bannerRef.current) {
    // this conditional block never runs, so bannerIndent is never defined
      const bannerWidth = bannerRef.current.getBoundingClientRect().width;
      bannerIndent.current = `${bannerWidth}px`;
    }
  }, []);

  return (
    <>
      <Banner ref={bannerRef} />
      <ComponentTwo bannerIndent={bannerIndent.current} />
    </>
  )
}

転送された参照を受け取るコンポーネント:

const Banner = React.forwardRef<HTMLDivElement, Props> ((props, ref) => (
  <div ref={ref} />
));

転送された参照から派生したデータを必要とするコンポーネント:

const ComponentTwo = (props: {bannerIndent?: string}) => (
  <StyledDiv bannerIndent={props.bannerIndent} />
)

// styled.div is a styled-component
const StyledDiv = styled.div<{bannerIndent?: string}>`
  ... // styles, some of which depend on bannerIndent
`

forwardRef が常に null または未定義であることを議論する既存の SO の質問への回答は、ref が最初のレンダリング後にのみ定義されることを指摘しています。useEffect は最初のレンダリングの後に実行する必要がありますが、bannerRef.current はまだ null であるため、これは問題ではないと思います。

通常の ref を使用して Banner コンポーネント内で使用すると、 useEffect フックで bannerIndent の値を設定するロジックが正しく機能します。ただし、(転送された参照を使用して生成された) bannerWidth を Banner コンポーネントの兄弟に渡すことができるように、参照を親コンポーネントに配置する必要があります。

助けていただければ幸いです:D

4

0 に答える 0