web-dev-qa-db-ja.com

Reactフック-ScrollIntoViewを使用するために参照を子に渡します

2つのコンポーネントがあります。親子。

親コンポーネント内にボタンがあります。ユーザーがそのボタンをクリックした場合、子コンポーネント内の別のボタンにScrollIntoViewを実行します。

子ボタンaへの参照を定義して、親ボタンonClick内で次のことができるようにしたいと思います。

ref.scrollIntoView({block: 'end', behavior: 'smooth'});

子コンポーネントのボタンまでスクロールします。

これは縮小された例です:

ParentComponent.jsx

import React, {useRef} from 'react';
import ChildComponent from './ChildComponent';

const ParentComponent = props => {
  const childReference = useRef(null);

  const onClick = () => {
    childReference.scrollIntoView({block: 'end', behavior: 'smooth'});
  }

  return (
    <>
      <...some other components>
      <Button onClick={onClick}>Click me to be forwarded</Button>
      <ChildComponent ref={childReference}/>
    </>
  );
};

ChildComponent.jsx

import React from 'react';

const ChildComponent = (props, ref) => {

  const { name, value, description } = props;

  return (
    <...some other components>
    <Button ref={ref}>You should be forwarded to me</Button>
  );
};

ChildComponent.propTypes = {
  name: PropTypes.string.isRequired,
  value: PropTypes.number,
  description: PropTypes.string,
};

ChildComponent.defaultProps = {
  value: 0,
  description: '',
};

export default React.forwardRef(ChildComponent);

私は上記のコードを知っています機能しません、それは私が達成しようとしていることを説明するためだけのものでした。

私はグーグルで見つけた他のすべてのソリューションを実際に試しましたが、それらはすべてとても簡単に見えますが、それらのどれも私の使用例ではうまくいかないようです。 forwardRefも使用してみましたが、それでも問題は解決しません。

更新

何がうまくいかないのか私は少し漠然としていたと思います。実装でさまざまなエラーメッセージが表示されます。

以下はその1つです。

関数コンポーネントに参照を与えることはできません。この参照にアクセスしようとすると失敗します。 React.forwardRef()を使用するつもりでしたか?

解決

はい。 @Vencovskyが提供するソリューションを使用して、ここで部品を組み立てると思いました。

これは、質問に見られる2つのサンプルコンポーネントを含む完全な実装です。

ParentComponent.jsx

import React, { useRef } from 'react';
import ChildComponent from './ChildComponent';

const ParentComponent = props => {
  const childReference = useRef(null);

  const scrollIntoView = () => {
    childReference.current.scrollIntoView({block: 'center', inline: 'center', behavior: 'smooth'});
  }

  return (
    <>
    <...some other component>
    <Button onClick={scrollIntoView}>Click me to be forwarded</Button>
    <ChildComponent ref={childReference}
    </>
  );
};

export default ParentComponent;

ChildComponent.jsx

import React, {forwardRef} from 'react';
import PropTypes from 'prop-types';

const ChildComponent = forwardRef((props, ref) => {
  const { name, value, description } = props;

  return(
    <>
      <...some other components>
      <Button ref={ref}>You should be forwarded to me</Button>
    </>
  );
});

ChildComponent.propTypes = {
  name: PropTypes.string.isRequired,
  value: PropTypes.number,
  description: PropTypes.string,
};

ChildComponent.defaultProps = {
  value: 0,
  description: '',
};

export default ChildComponent;
3
Zeliax

編集2:

あなたは次のようなことをしていると思います

_const ChildComponent = (props, ref) => { ... }

ChildComponent.propTypes = { ... }

export default React.forwardRef(ChildComponent)
_

しかし、あなたがする必要があるのは、次のように_React.forwardRef_の後にpropTypesを渡すことです:

_const ChildComponent = (props, ref) => { ... }          

const ForwardComponent = React.forwardRef(ChildComponent)

ForwardComponent.propTypes = { ... }

export default ForwardComponent
_

それを行うより良い方法は次のようになります

_//                     using forwarRef
const ChildComponent = React.forwarRef((props, ref) => {

  const { name, value, description } = props;

  return (
    <...some other components>
    <Button ref={ref}>You should be forwarded to me</Button>
  );
});
_

その後、propTypesを変更して別のコンポーネントを作成する必要はありません。

編集:

あなたの編集として、_React.forwardRef_を使用するのを忘れていることがわかります。

追加する必要があります

_export default React.forwardRef(ChildComponent)
_

ChildComponentファイルに転送します(forwardRefでエクスポートします)。


何が機能していませんか?エラーが発生していますか?何が起こっているのかをもっとよく説明すべきですが、私は推測してみます。

それが機能しないようにすることができる何かがあります。

  1. _ref.current.foo_の代わりに _ref.foo_ を使用する必要があります
  2. @JeroenWienkが言ったように:

    ボタンもカスタムコンポーネントのようです。参照が内部のHTMLボタン要素に渡されていることを確認しますか?

  3. 機能コンポーネントの2番目のパラメーターを使用するには、 _React.forwardRef_ を使用する必要があります。例えばexport default React.forwardRef(ChildComponent)
1
Vencovsky