我有两个组成部分:

父组件 子组件

我试图从Parent调用Child的方法,我尝试了这种方式,但不能得到一个结果:

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

是否有一种方法从父调用子方法?

注意:子组件和父组件在两个不同的文件中。


当前回答

使用useEffect的替代方法:

家长:

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

孩子们:

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

其他回答

我希望我没有重复上面的内容但是如果传递一个回调道具来设置父类中的函数呢?这很有效,也很简单。(添加的代码在////之间)

class Parent extends Component {
  ///// 
  getAlert = () => {} // initial value for getAlert

  setGetAlertMethod = (newMethod) => {
    this.getAlert = newMethod;
  }
  /////

  render() {
    return (
      <Child setGetAlertMethod={this.setGetAlertMethod}>
        <button onClick={this.getAlert}>Click</button>
      </Child>
      );
    }
  }



class Child extends Component {
  /////
  componentDidMount() {
    this.props.setGetAlertMethod(this.getAlert);
  }
  /////

  getAlert() => {
    alert('clicked');
  }

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

首先,让我声明一下,在React领域,这通常不是做事的方式。通常,您要做的是将功能传递给道具中的子元素,并在事件中传递子元素的通知(或者更好的方法是:分派)。

但如果必须在子组件上公开命令式方法,则可以使用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()的文档在这里:

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

使用类组件的遗留API (>= 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中不太常见:

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>

我尝试使用createRef或useRef。它们都返回null。

其次,这个答案提出通过一个道具来设置一个在我看来最合理的函数。但如果子组件用于多个地方,则应该将额外的道具添加到其他地方。此外,如果您想在孙辈中调用一个方法,这个方法可能太啰嗦或太冗长。

所以我用一种非常原始的方式创建了我自己的函数存储。

下面是functionStore.js文件

const fns = {};

export function setFn(componentName, fnName, fn) {
  if (fns[componentName]) {
    fns[componentName][fnName] = fn;
  } else {
    fns[componentName] = { fnName: fn };
  }
}

export function callFn(componentName, fnName) {
  fns[componentName][fnName]();
}

我只是设置了需要从任何组件调用的函数。

import { setFn } from "./functionStore";
export class AComponent extends React.Component {
  componentDidMount() {
    setFn("AComponent", "aFunc", this.aFunc);
  }
  aFunc = () => { console.log("aFunc is called!"); };
}

然后我从其他组件调用它

import { callFn } from "./functionStore";
export class BComponent extends React.Component {
  
  // just call the function
  bFunc = () => { 
    callFn("AComponent", "aFunc");
  };
}

一个缺点是要调用的函数应该是无参数的。但这也可能以某种方式解决。目前,我不需要传递参数。

我们可以用另一种方式使用refs,如-

我们将创建一个父元素,它将呈现一个<Child/>组件。如您所见,对于将要呈现的组件,您需要添加ref属性并为其提供名称。 然后,位于父类中的triggerChildAlert函数将访问this context的refs属性(当triggerChildAlert函数被触发时,它将访问子引用,并且它将具有子元素的所有函数)。

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

这里是源代码- 希望对你有所帮助!

用这种方法可以很容易地实现这一点

步骤,

Create a boolean variable in the state in the parent class. Update this when you want to call a function. Create a prop variable and assign the boolean variable. From the child component access that variable using props and execute the method you want by having an if condition. 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> ); } }