親から子メソッドを呼び出す


474

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

  1. 親コンポーネント
  2. 子コンポーネント

親から子のメソッドを呼び出そうとしていましたが、この方法を試しましたが結果を取得できませんでした

class Parent extends Component {
  render() {
    return (
      <Child>
        <button onClick={Child.getAlert()}>Click</button>
      </Child>
      );
    }
  }

class Child extends Component {
  getAlert() {
    alert('clicked');
  }

  render() {
    return (
      <h1 ref="hello">Hello</h1>
    );
  }
}

親から子のメソッドを呼び出す方法はありますか?

注:子コンポーネントと親コンポーネントは2つの異なるファイルにあります


私はこれに非常に遅れていますが、Reactについても学習しているので、親が子メソッドを呼び出す必要がある場合について知りたいのですが。説明していただけますか?
Akshay Raut

誰でもこれを矢印関数からどのように知っていますか?stackoverflow.com/questions/60015693/...
トーマスSegato

@AkshayRaut IMOは良いユースケースです。リセット関数と送信関数を備えた汎用フォームで、後者はフォームの値を返します。
ジュリアンK

回答:


702

まず、これは一般的にReactの土地で物事を進める方法ではないことを述べさせてください。通常、あなたがしたいことは、小道具で子供に機能を渡し、イベントで子供からの通知を渡すことです(またはもっと良いのは:)dispatch

ただし、子コンポーネントで命令型メソッドを公開する必要がある場合は、refsを使用できます。これは脱出用ハッチであり、通常はより良いデザインが利用可能であることを示しています。

以前は、refはクラスベースのコンポーネントでのみサポートされていました。React Hooksの登場により、もはやそうではありません

フックと関数コンポーネントの使用(>= react@16.8

const { forwardRef, useRef, useImperativeHandle } = React;

// We need to wrap component in `forwardRef` in order to gain
// access to the ref object that is assigned using the `ref` prop.
// This ref is passed as the second parameter to the function component.
const Child = forwardRef((props, ref) => {

  // The component instance will be extended
  // with whatever you return from the callback passed
  // as the second argument
  useImperativeHandle(ref, () => ({

    getAlert() {
      alert("getAlert from Child");
    }

  }));

  return <h1>Hi</h1>;
});

const Parent = () => {
  // In order to gain access to the child component instance,
  // you need to assign it to a `ref`, so we call `useRef()` to get one
  const childRef = useRef();

  return (
    <div>
      <Child ref={childRef} />
      <button onClick={() => childRef.current.getAlert()}>Click</button>
    </div>
  );
};

ReactDOM.render(
  <Parent />,
  document.getElementById('root')
);
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>

<div id="root"></div>

のドキュメントuseImperativeHandle()こちら

useImperativeHandleの使用時に親コンポーネントに公開されるインスタンス値をカスタマイズしますref

クラスコンポーネントの使用(>= react@16.4

const { Component } = React;

class Parent extends Component {
  constructor(props) {
    super(props);
    this.child = React.createRef();
  }

  onClick = () => {
    this.child.current.getAlert();
  };

  render() {
    return (
      <div>
        <Child ref={this.child} />
        <button onClick={this.onClick}>Click</button>
      </div>
    );
  }
}

class Child extends Component {
  getAlert() {
    alert('getAlert from Child');
  }

  render() {
    return <h1>Hello</h1>;
  }
}

ReactDOM.render(<Parent />, document.getElementById('root'));
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>

レガシーAPI(<= react@16.3

歴史的な目的のために、16.3より前のバージョンのReactで使用するコールバックベースのスタイルを次に示します。

const { Component } = React;
const { render } = ReactDOM;

class Parent extends Component {
  render() {
    return (
      <div>
        <Child ref={instance => { this.child = instance; }} />
        <button onClick={() => { this.child.getAlert(); }}>Click</button>
      </div>
    );
  }
}

class Child extends Component {
  getAlert() {
    alert('clicked');
  }

  render() {
    return (
      <h1>Hello</h1>
    );
  }
}


render(
  <Parent />,
  document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>


23
私は疲れましたが、このエラー「_this2.refs.child.getAlertは関数ではありません」で終わりました
N8FURY

22
これconnectは、元のインスタンスをラップする高次コンポーネントを返すためです。getWrappedInstance()元のコンポーネントを取得するには、最初に接続されたコンポーネントを呼び出す必要があります。次に、その上でインスタンスメソッドを呼び出すことができます。
rossipedia 16

16
これは本当に良いパターンではありません。言うまでもなく、文字列の参照は眉をひそめています。小道具を子コンポーネントに渡してから、親でボタンをクリックして親の状態を変更し、状態アイテムを子に渡して子のをトリガーし、それをトリガーcomponentWillReceivePropsとして使用することをお勧めします。
ffxsam 2017年

8
いいえ、通常、これは最良のパターンでありません。必要な場合は、エスケープハッチのようなものであり、緊急時にのみ使用する必要があります。また、この回答は文字列参照がまだ残っているときに書かれたものであり、最近では「正しい」方法ではないことは間違いありません。
rossipedia 2017年

35
子コンポーネントのメソッドを呼び出すのと同じくらい簡単なことを実行するためのロジックの迷路を作成することがベストプラクティスである場合、私はベストプラクティスに同意しません。
aaaaaa

149

ここで別のパターンを使用できます。

class Parent extends Component {
 render() {
  return (
    <div>
      <Child setClick={click => this.clickChild = click}/>
      <button onClick={() => this.clickChild()}>Click</button>
    </div>
  );
 }
}

class Child extends Component {
 constructor(props) {
    super(props);
    this.getAlert = this.getAlert.bind(this);
 }
 componentDidMount() {
    this.props.setClick(this.getAlert);
 }
 getAlert() {
    alert('clicked');
 }
 render() {
  return (
    <h1 ref="hello">Hello</h1>
  );
 }
}

clickChild子がマウントされるときに親のメソッドを設定することです。このように、親のボタンをクリックするclickChildと、子のを呼び出すボタンが呼び出されますgetAlert

これはあなたの子供がラップされているconnect()のでgetWrappedInstance()ハックする必要がない場合にも機能します。

onClick={this.clickChild}親がレンダリングされると子がマウントされないため、親では使用できないことに注意してくださいthis.clickChildいないまだ割り当てられていないん。onClick={() => this.clickChild()}ボタンをクリックすると、this.clickChild既に割り当てられているはずなので、使用は問題ありません。


5
私が取得_this2.clickChild is not a functionなぜ?
tatsu

1
用事これは私の仕事:github.com/kriasoft/react-starter-kit/issues/...
タツ

5
どちらもうまくいきませんでした。これだけの答えは働いた:github.com/kriasoft/react-starter-kit/issues/...
タツ

2
これは興味深いテクニックです。それは非常にきれいで、どんな規則にも違反しないようです。しかし、あなたがバインドを追加した場合、私はあなたの答えがより完全になると思います(そして期待に応えます)。答えがとても気に入ったので、この関連するGithubの問題に投稿しました。
-joeytwiddle

7
これは受け入れられる答えであるはずです
イエスゴメス

27

https://facebook.github.io/react/tips/expose-component-functions.html その他の回答については、こちらを参照してくださいrefここにReact子コンポーネントのメソッドを呼び出す

「reason」コンポーネントの参照を調べることで、カプセル化を壊し、使用されているすべての場所を注意深く調べなければ、そのコンポーネントをリファクタリングすることが不可能になります。このため、状態のように、refをコンポーネントのプライベートとして扱うことを強くお勧めします。

一般に、データは小道具を介してツリーの下を渡されるべきです。これにはいくつかの例外があります(.focus()の呼び出しや、実際に状態を「変更」しない1回限りのアニメーションのトリガーなど)が、「set」と呼ばれるメソッドを公開しているときは常に、プロップは通常より良い選択。内部の入力コンポーネントがそのサイズと外観を気にしないようにし、祖先がそれを行わないようにします。


5
これがこの回答の出典です:Discussion.reactjs.org/t/…。他の人を引用することに問題はありませんが、少なくともいくつかの参照を入れてください。
浄土

1
これはどのくらい正確にカプセル化をプロップ以上壊しますか?
Timmmm

16

useEffectを使用した代替方法:

親:

const [refresh, doRefresh] = useState(0);
<Button onClick={()=>doRefresh(refresh+1)} />
<Children refresh={refresh} />

子供達:

useEffect(() => {
    refresh(); //children function of interest
  }, [props.refresh]);

2
賛成票が増えるはずです
Ali Al Amine

Ps。フォームを再レンダリングするだけの場合(たとえば、入力フィールドをリセットする場合)、useEffectを含める必要さえありません。コンポーネントに送信されるプロップを変更するだけです
Matt Fletcher

8

別の方法で参照を使用することができます

親要素を作成し<Child/>ます。コンポーネントをレンダリングします。ご覧のように、レンダリングされるコンポーネントでは、ref属性を追加して名前を付ける必要があります。
次に、triggerChildAlert親クラスにあるtriggerChildAlert関数がthisコンテキストのrefsプロパティにアクセスします(関数がトリガーされると、子参照にアクセスし、子要素のすべての関数が含まれます)。

class Parent extends React.Component {
    triggerChildAlert(){
        this.refs.child.callChildMethod();
        // to get child parent returned  value-
        // this.value = this.refs.child.callChildMethod();
        // alert('Returned value- '+this.value);
    }

    render() {
        return (
            <div>
                {/* Note that you need to give a value to the ref parameter, in this case child*/}
                <Child ref="child" />
                <button onClick={this.triggerChildAlert}>Click</button>
            </div>
        );
    }
}  

これで、以前に理論的に設計された子コンポーネントは次のようになります。

class Child extends React.Component {
    callChildMethod() {
        alert('Hello World');
        // to return some value
        // return this.state.someValue;
    }

    render() {
        return (
            <h1>Hello</h1>
        );
    }
}

これがソースコードです-
希望があなたを助けます!



4

Childが親に再利用可能な特性を提供したいという理由だけでこれを行う場合は、代わりにrender-props使用すること検討できます。

その手法は、実際には構造を上下逆にします。これでChild親がラップされるので、名前をAlertTrait以下に変更しました。名前Parentは継続性を保つために付けましたが、実際には親ではありません。

// Use it like this:

  <AlertTrait renderComponent={Parent}/>


class AlertTrait extends Component {
  // You may need to bind this function, if it is stateful
  doAlert() {
    alert('clicked');
  }
  render() {
    return this.props.renderComponent(this.doAlert);
  }
}

class Parent extends Component {
  render() {
    return (
      <button onClick={this.props.doAlert}>Click</button>
    );
  }
}

この場合、AlertTraitは1つ以上の特性を提供しますrenderComponent。これは、プロップとして渡されたコンポーネントにプロップとして渡されます。

親はdoAlert小道具として受け取り、必要なときに呼び出すことができます。

(分かりやすくするためrenderComponentに、上の例では小道具を呼び出しました。しかし、上記のリンクされたReactのドキュメントでは、単にそれを呼び出していrenderます。)

トレイトコンポーネントは、そのレンダー機能で、親の周囲のものをレンダリングできますが、親の内部には何もレンダリングしません。実際には、別の小道具(例:renderChild。親はそのレンダーメソッドで使用できます。

これはOPが要求するものとは少し異なりますが、再利用可能な特性を作成したいと考え、子コンポーネントがそれを行うための良い方法であると考えたために、ここで(私たちのように)終わる人もいます。


:ここでは、再利用可能な特性を作成するためのパターンの便利なリストがありますreactjs.org/blog/2016/07/13/...
joeytwiddle

N個のストップウォッチとそれらをすべて再起動する1つのボタンがある場合はどうでしょうか。ここで小道具をどのように使用すると便利ですか?
vsync

@vsyncこの方法があなたの仕事に役立つかどうかはわかりません。しかし、brickingupの答えが役立つかもしれません。注彼らが設定することthis.clickChild = clickができますが、それらのすべてを格納する必要がありますので、あなたの複数のストップウォッチは、複数の機能を渡しますthis.watchRestartFuncs[watchId] = restartWatch
joeytwiddle

1

この方法でこれを簡単に達成できます

手順-

  1. 親クラスの状態にブール変数を作成します。関数を呼び出したいときに更新します。
  2. prop変数を作成し、ブール変数を割り当てます。
  3. 子コンポーネントから、propsを使用してその変数にアクセスし、if条件を使用して必要なメソッドを実行します。

    class Child extends Component {
       Method=()=>{
       --Your method body--
       }
       render() {
         return (
        //check whether the variable has been updated or not
          if(this.props.updateMethod){
            this.Method();
          }
         )
       }
    }
    
    class Parent extends Component {
    
    constructor(){
      this.state={
       callMethod:false
      }
    
    }
    render() {
       return (
    
         //update state according to your requirement
         this.setState({
            callMethod:true
         }}
         <Child updateMethod={this.state.callMethod}></Child>
        );
       }
    }

これをサンドボックス化したいかもしれません。親の状態がtrueに設定されているため、子メソッドが継続的に実行されるため、無限ループに陥るようです。
Isaac Pak

@IsaacPakええ、それで私はそこにコメントを残しました、あなたはあなたの要件に従って状態を更新しなければならないと言っています。その後、無限ループとして実行されません。
Kusal Kithmal

1

私はuseEffectこれをすべて行うことの頭痛を克服するためにフックを使用しているので、次のように変数を子に渡します:

<ParentComponent>
 <ChildComponent arbitrary={value} />
</ParentComponent>
useEffect(() => callTheFunctionToBeCalled(value) , [value]);

1

ここに提示された解決策のいずれにも満足できませんでした。基本的なpropsオブジェクト以外のいくつかのReact機能に依存せずに純粋なJavascriptを使用して実行できる非常に単純なソリューションが実際にあります。これにより、どちらの方向(親->子、子->親)にも通信できるという利点があります。親コンポーネントから子コンポーネントにオブジェクトを渡す必要があります。このオブジェクトは、私が「双方向参照」または略してbiRefと呼んでいます。基本的に、オブジェクトには、親が公開したい親のメソッドへの参照が含まれています。また、子コンポーネントは、親が呼び出すことができるオブジェクトにメソッドをアタッチします。このようなもの:

// Parent component.
function MyParentComponent(props) {

   function someParentFunction() {
      // The child component can call this function.
   }

   function onButtonClick() {
       // Call the function inside the child component.
       biRef.someChildFunction();
   }

   // Add all the functions here that the child can call.
   var biRef = {
      someParentFunction: someParentFunction
   }

   return <div>
       <MyChildComponent biRef={biRef} />
       <Button onClick={onButtonClick} />
   </div>;
}


// Child component
function MyChildComponent(props) {

   function someChildFunction() {
      // The parent component can call this function.
   }


   function onButtonClick() {
      // Call the parent function.
      props.biRef.someParentFunction();
   }

   // Add all the child functions to props.biRef that you want the parent
   // to be able to call.
   props.biRef.someChildFunction = someChildFunction;

   return <div>
       <Button onClick={onButtonClick} />
   </div>;
}

このソリューションのもう1つの利点は、単一のプロパティのみを使用して、親と子に関数を渡しながら、親と子により多くの関数を追加できることです。

上記のコードの改善点は、親関数と子関数を直接biRefオブジェクトに追加するのではなく、サブメンバーに追加することです。親関数は「親」というメンバーに追加する必要がありますが、子関数は「子」というメンバーに追加する必要があります。

// Parent component.
function MyParentComponent(props) {

   function someParentFunction() {
      // The child component can call this function.
   }

   function onButtonClick() {
       // Call the function inside the child component.
       biRef.child.someChildFunction();
   }

   // Add all the functions here that the child can call.
   var biRef = {
      parent: {
          someParentFunction: someParentFunction
      }
   }

   return <div>
       <MyChildComponent biRef={biRef} />
       <Button onClick={onButtonClick} />
   </div>;
}


// Child component
function MyChildComponent(props) {

   function someChildFunction() {
      // The parent component can call this function.
   }


   function onButtonClick() {
      // Call the parent function.
      props.biRef.parent.someParentFunction();
   }

   // Add all the child functions to props.biRef that you want the parent
   // to be able to call.
   props.biRef {
       child: {
            someChildFunction: someChildFunction
       }
   }

   return <div>
       <Button onClick={onButtonClick} />
   </div>;
}

親関数と子関数をbiRefオブジェクトの別々のメンバーに配置することで、2つの関数を明確に分離し、どちらが親または子に属しているかを簡単に確認できます。また、同じ機能が両方にある場合に、子コンポーネントが誤って親機能を上書きするのを防ぐのにも役立ちます。

最後にもう1つ注意してください。親コンポーネントはvarでbiRefオブジェクトを作成しますが、子コンポーネントはpropsオブジェクトを通じてアクセスします。親でbiRefオブジェクトを定義せずに、独自のpropsパラメータを介して親からそのオブジェクトにアクセスするのは魅力的な場合があります(UI要素の階層の場合など)。子は、親で呼び出されている関数が実際には祖父母に属している可能性がある場合、親に属していると考える可能性があるため、危険です。あなたがそれに気づいている限り、これには何の問題もありません。親子関係以外の階層をサポートする理由がない限り、親コンポーネントでbiRefを作成するのが最善です。



0

メソッドを呼び出す最も基本的な方法は、子コンポーネントにリクエストを設定することだと思います。次に、子が要求を処理するとすぐに、コールバックメソッドを呼び出して要求をリセットします。

リセットメカニズムは、同じリクエストを互いに何度も送信できるようにするために必要です。

親コンポーネント内

親のrenderメソッドで:

const { request } = this.state;
return (<Child request={request} onRequestHandled={()->resetRequest()}/>);

親が子と2方向で通信するには、2つのメソッドが必要です。

sendRequest() {
  const request = { param: "value" };
  this.setState({ request });
}

resetRequest() {
  const request = null;
  this.setState({ request });
}

子コンポーネント内

子はその内部状態を更新し、小道具からのリクエストをコピーします。

constructor(props) {
  super(props);
  const { request } = props;
  this.state = { request };
}

static getDerivedStateFromProps(props, state) {
  const { request } = props;
  if (request !== state.request ) return { request };
  return null;
}

次に、最後にリクエストを処理し、リセットを親に送信します。

componentDidMount() {
  const { request } = this.state;
  // todo handle request.

  const { onRequestHandled } = this.props;
  if (onRequestHandled != null) onRequestHandled();
}

0

親から子関数をトリガーする別の方法はcomponentDidUpdate、子コンポーネントで関数を利用することです。triggerChildFunc親から子に小道具を渡しnullます。最初はです。ボタンがクリックされると値が関数に変わり、Childが変化しcomponentDidUpdate、独自の内部関数を呼び出すことに気づきます。

プロップtriggerChildFuncが関数に変更されるため、親へのコールバックも取得します。親が関数がいつ呼び出されたかを知る必要がない場合、値triggerChildFuncはたとえばからnullに変わる可能性がありますtrue

const { Component } = React;
const { render } = ReactDOM;

class Parent extends Component {
  state = {
    triggerFunc: null
  }

  render() {
    return (
      <div>
        <Child triggerChildFunc={this.state.triggerFunc} />
        <button onClick={() => {
          this.setState({ triggerFunc: () => alert('Callback in parent')})
        }}>Click
        </button>
      </div>
    );
  }
}

class Child extends Component {
  componentDidUpdate(prevProps) {
    if (this.props.triggerChildFunc !== prevProps.triggerChildFunc) {
      this.onParentTrigger();
    }
  }

  onParentTrigger() {
    alert('parent triggered me');

    // Let's call the passed variable from parent if it's a function
    if (this.props.triggerChildFunc && {}.toString.call(this.props.triggerChildFunc) === '[object Function]') {
      this.props.triggerChildFunc();
    }
  }

  render() {
    return (
      <h1>Hello</h1>
    );
  }
}


render(
  <Parent />,
  document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='app'></div>

CodePen:https ://codepen.io/calsal/pen/NWPxbJv?editors=1010


0

ここに私のデモ:https : //stackblitz.com/edit/react-dgz1ee?file=styles.css

useEffect子コンポーネントのメソッドを呼び出すために使用しています。私は試してみましたProxy and Setter_Getterが、今のところuseEffect、親から子メソッドを呼び出すより便利な方法のようです。使用するProxy and Setter_Getterには、最初にレンダリングする要素がref.current return => <div/>'の特異性を通じてobjectLikeの要素であるため、最初に克服する必要がある微妙な点があるようです。に関してはuseEffect、このアプローチを活用して、子供に対して何をしたいかに応じて親の状態を設定することもできます。

私が提供したデモのリンクには、私のドラフトが入ったReactJSの完全なコードが含まれているので、私のソリューションのワークフローを理解できます。

ここでは、私のReactJSのスニペットに関連するコードのみを提供しています。:

import React, {
  Component,
  createRef,
  forwardRef,
  useState,
  useEffect
} from "react"; 

{...}

// Child component
// I am defining here a forwardRef's element to get the Child's methods from the parent
// through the ref's element.
let Child = forwardRef((props, ref) => {
  // I am fetching the parent's method here
  // that allows me to connect the parent and the child's components
  let { validateChildren } = props;
  // I am initializing the state of the children
  // good if we can even leverage on the functional children's state
  let initialState = {
    one: "hello world",
    two: () => {
      console.log("I am accessing child method from parent :].");
      return "child method achieve";
    }
  };
  // useState initialization
  const [componentState, setComponentState] = useState(initialState);
  // useEffect will allow me to communicate with the parent
  // through a lifecycle data flow
  useEffect(() => {
    ref.current = { componentState };
    validateChildren(ref.current.componentState.two);
  });

{...}

});

{...}

// Parent component
class App extends Component {
  // initialize the ref inside the constructor element
  constructor(props) {
    super(props);
    this.childRef = createRef();
  }

  // I am implementing a parent's method
  // in child useEffect's method
  validateChildren = childrenMethod => {
    // access children method from parent
    childrenMethod();
    // or signaling children is ready
    console.log("children active");
  };

{...}
render(){
       return (
          {
            // I am referencing the children
            // also I am implementing the parent logic connector's function
            // in the child, here => this.validateChildren's function
          }
          <Child ref={this.childRef} validateChildren={this.validateChildren} />
        </div>
       )
}

0

私たちは、カスタムフックと呼んでいますuseCounterKey。counterKey、つまりゼロからカウントアップするキーを設定するだけです。それが返す関数はキーをリセットします(つまり、インクリメント)。(これはReactでコンポーネントをリセットするための最も慣用的な方法だと思います。キーをバンプするだけです。)

ただし、このフックは、何かを実行するためにクライアントに1回限りのメッセージを送信する必要がある状況でも機能します。たとえば、特定の親イベントに子のコントロールをフォーカスするために使用します-キーが更新されるたびにオートフォーカスします。(プロップがさらに必要な場合は、キーをリセットする前にプロップを設定して、イベントが発生したときに使用できるようにすることができます。)

このメソッドには学習曲線が少しありますが、典型的なイベントハンドラーほど簡単ではありませんが、Reactでこれを処理する最も慣用的な方法のようです(キーが既にこのように機能しているため)。Defはこの方法に関するフィードバックを受け入れていますが、うまく機能しています!

// Main helper hook:
export function useCounterKey() {
  const [key, setKey] = useState(0);
  return [key, () => setKey(prev => prev + 1)] as const;
}

使用例:

// Sample 1 - normal React, just reset a control by changing Key on demand
function Sample1() {
  const [inputLineCounterKey, resetInputLine] = useCounterKey();

  return <>
    <InputLine key={inputLineCounterKey} />
    <button onClick={() => resetInputLine()} />
  <>;
}

// Second sample - anytime the counterKey is incremented, child calls focus() on the input
function Sample2() {
  const [amountFocusCounterKey, focusAmountInput] = useCounterKey();

  // ... call focusAmountInput in some hook or event handler as needed

  return <WorkoutAmountInput focusCounterKey={amountFocusCounterKey} />
}

function WorkoutAmountInput(props) {
  useEffect(() => {
    if (counterKey > 0) {
      // Don't focus initially
      focusAmount();
    }
  }, [counterKey]);

  // ...
}

counterKeyコンセプトについては、Kent Doddsのクレジットです。)


-1

ここにバグがありますか?注意点:forwardRef、useRef、useImperativeHandleを使用したrossipediaのソリューションに同意します

refはReactクラスコンポーネントからのみ作成できるというオンラインの誤った情報がありますが、前述のフックを使用すれば、実際に関数コンポーネントを使用できます。注、コンポーネントをエクスポートするときにwithRouter()を使用しないようにファイルを変更した後でのみ、フックは機能しました。すなわちからの変更

export default withRouter(TableConfig);

代わりに

export default TableConfig;

後から考えると、とにかくそのようなコンポーネントにはwithRouter()は必要ありませんが、通常はそれが原因で問題が発生することはありません。私の使用例では、構成値の表示と編集を処理するテーブルを作成するコンポーネントを作成しました。また、この子コンポーネントに、親フォームのリセットボタンが押されたときに状態値をリセットするように伝えたいと考えていました。子コンポーネントTableConfigを含むファイルからwithRouter()を削除するまで、UseRef()はrefまたはref.current(nullのままになる)を適切に取得しません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.