React 如何实现父组件调用子组件的方法

阅读时长 7 分钟读完

在 React 中,组件之间的协作是很常见的。有时候,我们需要在一个父组件中调用其中一个子组件的方法。这种情况下,我们需要使用 React 的 ref 属性,它可以让我们获取到一个组件的实例,并且通过这个实例调用它的方法。

在本文中,我们将介绍如何使用 ref 属性来实现父组件调用子组件的方法。我们将从基础知识出发,逐步深入,介绍许多有用的方法和技巧。

基础知识

在 React 中,每个组件都有自己的生命周期。当组件挂载到 DOM 中时,React 会对组件进行初始化,并且在适当的时候调用生命周期函数。其中,componentDidMount 是组件挂载后第一个被调用的生命周期函数。

componentDidMount 中,我们可以获取到组件实例。具体来说,我们可以使用 ref 属性来获取组件实例。例如,下面这个例子就展示了如何使用 ref 来获取组件实例:

-- -------------------- ---- -------
----- -------------- ------- --------------- -
  ------------ -
    -- ---
  -
  
  -------- -
    ------ ---------- ---------------
  -
-

----- --------------- ------- --------------- -
  ------------------- -
    --------------------------------- -- -------------- --
    ---------------------------------
  -
  
  -------- -
    ------ -
      -----
        --------------- ------------------- -- ------------------- - --------------- --
      ------
    --
  -
-

在这个例子中,ChildComponent 只是简单地渲染了一个 div。在 ParentComponent 中,我们通过在 ChildComponent 上设置 ref 属性来获取到 ChildComponent 的实例。然后在 ParentComponentcomponentDidMount 函数中,我们就可以通过获取到的实例来调用 someMethod 函数了。

更多用法

上面的例子只是实现了一个基本的功能。我们还可以使用更多的技巧来实现更加强大和灵活的功能。在下面,我们将介绍一些使用 ref 属性的常见方法和技巧。

获取 DOM 元素

在 React 中,我们可以使用 ReactDOM.findDOMNode 来获取到组件的 DOM 元素。例如,下面这个例子就展示了如何使用 ReactDOM.findDOMNode 来获取到组件的 input 元素的值:

-- -------------------- ---- -------
----- -------------- ------- --------------- -
  ---------- -
    ------ -----------------
  -
  
  -------- -
    ------ ------ ----------- -------------------- ------- -- ---------- - --- --
  -
-

----- --------------- ------- --------------- -
  ------------------- -
    ----- ----- - -----------------------------------------------------
    ------------------- -- -------
  -
  
  -------- -
    ------ -
      -----
        --------------- ------------------- -- ------------------- - --------------- --
      ------
    --
  -
-

在这个例子中,我们在 ChildComponent 中使用 ref 属性来获取到 input 元素的实例,并且在 getValue 函数中获取了它的值。在 ParentComponentcomponentDidMount 函数中,我们使用 ReactDOM.findDOMNode 来获取到 ChildComponent 的 DOM 元素,并且调用它的 getValue 函数来获取到 input 元素的值。

使用回调函数来实现动态更新

有时候,我们需要在子组件渲染完毕之后,通知父组件进行一些操作。比如,可能需要在父组件中根据子组件的大小,调整它的宽度或者高度。

为了实现这种功能,我们可以在子组件的 componentDidMount 函数中,调用父组件传递给它的一个回调函数。比如,下面这个例子就展示了如何使用回调函数来实现动态更新:

-- -------------------- ---- -------
----- -------------- ------- --------------- -
  ------------------- -
    ------------------------------------------------------
  -
  
  -------- -
    ------ ---- ------- -- --------- - --------- ---------------
  -
-

----- --------------- ------- --------------- -
  ----- - -
    ------ -----
    ------- -----
  -
  
  ---------------- - ------ -- -
    ----- ------- ------- - -----
    --------------------- ---------
  -
  
  -------- -
    ------ -
      -----
        --------------- ------------------------------- --
        ---------- --------- ----- --------------------------------------------
      ------
    --
  -
-

在这个例子中,ChildComponent 在渲染完毕之后,调用了父组件传递给它的 onMount 回调函数,并且把自己的位置信息作为参数传递了过去。在 ParentComponent 中,我们定义了一个 handleChildMount 函数来处理子组件的 onMount 回调,并且根据子组件的大小,更新了父组件的状态。最后,我们把父组件的状态展示在了页面中。

使用 forwardRef 来传递 ref

在 React 16.3 中,引入了一个新的 forwardRef API,它可以让我们简化 ref 的传递过程。使用 forwardRef,我们可以在子组件中声明自己希望获取到 ref 的位置,而不需要让父组件显式地传递 ref。例如,下面这个例子就展示了如何使用 forwardRef 来传递 ref

-- -------------------- ---- -------
----- -------------- - ------------------------ ---- -- -
  ----- ----------- - -- -- -
    -------------------------
  -
  
  ------ ------- --------------------------- -----------
---

----- --------------- ------- --------------- -
  -------- - ------------------
  
  -------- -
    ------ -
      -----
        --------------- ------------------- --
      ------
    --
  -
-

在这个例子中,我们用 forwardRef 包装了一个简单的按钮组件,这个组件可以通过 ref 调用父组件传递给它的 someMethod 函数。在 ParentComponent 中,我们定义了一个 childRef 来保存子组件的 ref,并且把这个 ref 传递给了 ChildComponent。在子组件中,我们可以通过 ref.current 来获取到子组件的实例,并且调用它的方法。

总结

在 React 中,通过使用 ref 属性,我们可以很方便地获取到组件的实例,并且调用它的方法。我们在本文中介绍了很多使用 ref 的方法和技巧,包括获取 DOM 元素、使用回调函数来实现动态更新、使用 forwardRef 来传递 ref 等等。这些技巧将会非常有用,并且可以让你在处理一些复杂的场景时,更加轻松自如。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/645af032968c7c53b0d3c460

纠错
反馈