从父级调用子方法 [英] Call child method from parent

查看:36
本文介绍了从父级调用子方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个组件:

  1. 父组件
  2. 子组件

我试图从 Parent 调用 Child 的方法,我尝试过这种方式但无法得到结果:

class Parent extends Component {使成为() {返回 (<孩子><button onClick={Child.getAlert()}>点击</button></孩子>);}}类子扩展组件{获取警报(){警报('点击');}使成为() {返回 (<h1 ref=你好">你好</h1>);}}

有没有办法从Parent调用Child的方法?

注意:子组件和父组件位于两个不同的文件中.

解决方案

首先,让我表示这通常不是在 React 领域处理事情的方式.通常你想要做的是在 props 中将功能传递给孩子,并在事件中传递来自孩子的通知(或者更好:调度).

但是如果您必须在子组件上公开一个命令式方法,您可以使用 参考.请记住,这是一个逃生舱口,通常表明有更好的设计可用.

<块引用>

以前,只有基于类的组件才支持引用.随着 React Hooks 的出现,情况不再如此

带有钩子的现代 React (v16.8+)

const { forwardRef, useRef, useImperativeHandle } = React;//我们需要将组件包裹在 `forwardRef` 中以获得//访问使用 `ref` 属性分配的 ref 对象.//这个 ref 作为第二个参数传递给函数组件.const Child = forwardRef((props, ref) => {//组件实例将被扩展//使用你从回调中返回的任何内容//作为第二个参数useImperativeHandle(ref, () => ({获取警报(){alert("getAlert from Child");}}));返回<h1>Hi</h1>;});const Parent = () =>{//为了获得对子组件实例的访问权限,//你需要将它分配给一个 `ref`,所以我们调用 `useRef()` 来获取一个const childRef = useRef();返回 (<div><子引用={childRef}/><button onClick={() =>childRef.current.getAlert()}>点击</button>

);};ReactDOM.render(<父/>,document.getElementById('root'));

<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin><<;/脚本><script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script><div id="root"></div>

useImperativeHandle() 的文档在这里:

<块引用>

useImperativeHandle 自定义使用 ref 时暴露给父组件的实例值.

使用类组件的旧 API (>= react@16.4)

const { Component } = React;类父扩展组件{构造函数(道具){超级(道具);this.child = React.createRef();}onClick = () =>{this.child.current.getAlert();};使成为() {返回 (<div><Child ref={this.child}/><button onClick={this.onClick}>点击</button>

);}}类子扩展组件{获取警报(){alert('getAlert from Child');}使成为() {return <h1>你好</h1>;}}ReactDOM.render(, document.getElementById('root'));

<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin><<;/脚本><script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script><div id="root"></div>

回调引用 API

回调风格的引用是实现这一目标的另一种方法,尽管在现代 React 中并不常见:

const { Component } = React;const { 渲染 } = ReactDOM;类父扩展组件{使成为() {返回 (<div><子引用={实例=>{ this.child = 实例;}}/><button onClick={() =>{ this.child.getAlert();}}>点击</button>

);}}类子扩展组件{获取警报(){警报('点击');}使成为() {返回 (<h1>你好</h1>);}}使成为(<父/>,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>

I have two components:

  1. Parent component
  2. Child component

I was trying to call Child's method from Parent, I tried this way but couldn't get a result:

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>
    );
  }
}

Is there a way to call Child's method from Parent?

Note: Child and Parent components are in two different files.

解决方案

First off, let me express that this is generally not the way to go about things in React land. Usually what you want to do is pass down functionality to children in props, and pass up notifications from children in events (or better yet: dispatch).

But if you must expose an imperative method on a child component, you can use refs. Remember this is an escape hatch and usually indicates a better design is available.

Previously, refs were only supported for Class-based components. With the advent of React Hooks, that's no longer the case

Modern React with Hooks (v16.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>

Documentation for useImperativeHandle() is here:

useImperativeHandle customizes the instance value that is exposed to parent components when using ref.

Legacy API using Class Components (>= 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>

Callback Ref API

Callback-style refs are another approach to achieving this, although not quite as common in modern 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>

这篇关于从父级调用子方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆