ReactJS - 如何从一个组件调用另一个组件的方法

59

我有两个组件。我想从第二个组件调用第一个组件的方法。我该怎么做?

这是我的代码。

第一个组件

class Header extends React.Component{

    constructor(){
        super();
    }

    checkClick(e, notyId){
       alert(notyId);
    }
}

export default Header;

第二部分

class PopupOver extends React.Component{

    constructor(){
        super();
        // here i need to call Header class function check click....
        // How to call Header.checkClick() from this class
    }

    render(){
        return (
            <div className="displayinline col-md-12 ">
                Hello
            </div>
        );
    }
}

export default PopupOver;

你为什么想这样做呢?我认为这不是一个好的做法,它会破坏组件模式。你有足够的插件来在一个地方管理事件:例如 RxJS(Flux,Redux…)。 - Maxim Shoustin
1
什么是破坏组件模式? - Kushal Jain
当组件独立时,重复使用它们会更加容易。如果您想实现您的目标-合并它们并创建一个组件。考虑一下当您更改父组件方法名称时的情况:之后您需要检查项目并相应地更改依赖项。 - Maxim Shoustin
你可以在github.com/burakozturk16/pigeon上查看。 - Phd. Burak Öztürk
3个回答

36
你可以这样做。
import React from 'react';

class Header extends React.Component {

constructor() {
    super();
}

checkClick(e, notyId) {
    alert(notyId);
}

render() {
    return (
        <PopupOver func ={this.checkClick } />
    )
}
};

class PopupOver extends React.Component {

constructor(props) {
    super(props);
    this.props.func(this, 1234);
}

render() {
    return (
        <div className="displayinline col-md-12 ">
            Hello
        </div>
    );
}
}

export default Header;

使用静态

var MyComponent = React.createClass({
 statics: {
 customMethod: function(foo) {
  return foo === 'bar';
  }
 },
   render: function() {
 }
});

MyComponent.customMethod('bar');  // true

1
我不想将PopupOver组件添加到Header组件中。还有其他解决方案吗? - Kushal Jain
你可以使用 React.statics 实现它 - Mohit Verma
有任何链接或示例吗? - Kushal Jain
5
这是针对这种情况的正确答案。但是,当两个组件不是父子关系,而是兄弟关系时,它在复杂的情况下并不适用。 - HoldOffHunger

11

实际上,React并不适用于从父组件调用子组件的方法。一些框架,比如Cycle.js,允许轻松地从父组件和子组件中访问数据,并对其进行反应。

此外,你很可能并不真正需要这样做。考虑将现有组件中的方法调用插入其中,这是一种更独立的解决方案。但是有时你仍然需要这样做,那么你就有几个选择:

  • 向下传递方法(如果它是子组件,则是最简单的方法之一,并且是传递的属性之一)
  • 添加事件库;在React生态系统中,Flux方法是最为人所知的,使用Redux库。你将所有事件分离成不同的状态和操作,并从组件中分派它们
  • 如果你需要在父组件中使用来自子组件的函数,可以将其封装在第三个组件中,并使用增强的props克隆父组件。

更新: 如果你需要共享一些与任何状态无关的功能(比如OOP中的静态函数),那么没有必要将其包含在组件中。只需单独声明并在需要时调用即可:

let counter = 0;
function handleInstantiate() {
   counter++;
}

constructor(props) {
   super(props);
   handleInstantiate();
}

谢谢,但我的两个组件是独立的,一个不依赖于另一个,我只需要从一个组件中调用另一个组件的函数,就像我们从另一个类中调用静态函数一样。 - Kushal Jain
如果您需要调用一个static函数,那么它可以被分离成一个普通函数。因此,将此函数放置在utils文件夹中,并在需要时导入它。如果涉及任何状态,则传递或进行外部状态管理。 - Bloomca
请给我一个小例子。 - Kushal Jain
我已经更新了这篇文章。基本上,只需将其声明为普通函数,并在需要时调用即可 - 没有必要将静态方法保留在类内部(除非您以面向对象的方式编写,但在React社区中通常不鼓励这样做)。 - Bloomca

2
您可以通过以下方式从父组件调用子组件的方法。
import React from 'react';

class Header extends React.Component {

    constructor() {
        super();
        this.childComponentRef;
    }

    getChildComponent = (childComponent) =>  {

        this.childComponentRef = childComponent;
        this.childComponentRef.sayHi();
        
    }

    render() {
        return (
            <ChildComponent getChildComponent={this.getChildComponent} />
        )
    }
};

class ChildComponent extends React.Component {

    componentDidMount () {
        this.props.getChildComponent(this);
    }

    sayHi = () => {
        alert("hi");
    }

    render() {
        return (
            <div className="displayinline col-md-12 ">
                Hello
            </div>
        );
    }
}

export default Header;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接