我有两个组件:

  1. 父组件
  2. 子组件

我试图从家长那里调用Child的方法,我try 了这种方法,但没有得到结果:

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

有没有办法从家长那里调用Child的方法?

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

推荐答案

首先,让我表达一下,这通常是一种在陆地上做事的方式.通常你想做的是在props 中将功能传递给子元素们,并在事件中传递来自子元素们的通知(或者更好的是:dispatch).

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

以前,只有基于类的组件才支持引用. 随着React Hooks岁的到来,情况不再是这样了

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>

useImperativeHandle() is here的文档:

useImperativeHandle自定义使用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>

回调引用API

回调风格的Ref是实现这一点的另一种方法,尽管在现代Reaction中不太常见:

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>

Javascript相关问答推荐

如何提取Cypress中文本

使用AJX发送表单后,$_Post看起来为空

为什么我的includes声明需要整个字符串?

防止用户在selectizeInput中取消 Select 选项

嵌套异步JavaScript(微任务和macrotask队列)

PrivateRoute不是路由组件错误

如何禁用附加图标点击的v—自动完成事件

在Vite React库中添加子模块路径

如何在模块层面提供服务?

如何根据当前打开的BottomTab Screeb动态加载React组件?

如何将多维数组插入到另一个多维数组中?

JQuery Click事件不适用于动态创建的按钮

在使用位板时,如何在Java脚本中判断Connect 4板中中柱的对称性?

搜索功能不是在分页的每一页上进行搜索

第一项杀死下一项,直到数组长度在javascript中等于1

AddEventListner,按键事件不工作

WebSocketException:远程方在未完成关闭握手的情况下关闭了WebSocket连接.&#三十九岁;

Reaction即使在重新呈现后也会在方法内部保留局部值

如何在Web项目中同步语音合成和文本 colored颜色 更改

如何在函数组件中保留对计时器的引用