从外部调用React组件方法

问题描述 投票:63回答:8

我想从React Element的实例调用React组件公开的方法。

例如,在这个jsfiddle https://jsfiddle.net/r6r8cp3z/中,我想从alertMessage参考中调用HelloElement方法。

有没有办法实现这一点,而无需编写额外的包装器?

编辑(从JSFiddle复制代码)

<div id="container"></div>
<button onclick="onButtonClick()">Click me!</button>
var onButtonClick = function () {

    //call alertMessage method from the reference of a React Element! Something like HelloElement.alertMessage()
    console.log("clicked!");
}

var Hello = React.createClass({displayName: 'Hello',

    alertMessage: function() {
        alert(this.props.name);                             
    },

    render: function() {
        return React.createElement("div", null, "Hello ", this.props.name);
    }
});

var HelloElement = React.createElement(Hello, {name: "World"});

React.render(
    HelloElement,
    document.getElementById('container')
);
reactjs
8个回答
45
投票

有两种方法可以访问内部函数。一个是实例级,就像你想要的那样,是另一个静态级别。

您需要在React.render返回时调用该函数。见下文。

静态的

看看ReactJS Statics。但请注意,静态函数无法访问实例级数据,因此this将为undefined

var onButtonClick = function () {
    //call alertMessage method from the reference of a React Element! 
    HelloRendered.alertMessage();
    //call static alertMessage method from the reference of a React Class! 
    Hello.alertMessage();
    console.log("clicked!");
}

var Hello = React.createClass({
    displayName: 'Hello',
    statics: {
        alertMessage: function () {
            alert('static message');
        }
    },
    alertMessage: function () {
        alert(this.props.name);
    },

    render: function () {
        return React.createElement("div", null, "Hello ", this.props.name);
    }
});

var HelloElement = React.createElement(Hello, {
    name: "World"
});

var HelloRendered = React.render(HelloElement, document.getElementById('container'));

然后做HelloRendered.alertMessage()


16
投票

我做过这样的事情:

class Cow extends React.Component {

    constructor (props) {
        super(props)
        this.state = {text: 'hello'}
    }

    componentDidMount () {
        if (this.props.onMounted) {
            this.props.onMounted({
                say: text => this.say(text)
            })
        }
    }

    render () {
        return (
            <pre>
                 ___________________
                < {this.state.text} >
                 -------------------
                        \   ^__^
                         \  (oo)\_______
                            (__)\       )\/\
                                ||----w |
                                ||     ||
            </pre>
        )
    }

    say (text) {
        this.setState({text: text})
    }

}

然后在其他地方:

class Pasture extends React.Component {

    render () {
        return (
            <div>
                <Cow onMounted={callbacks => this.cowMounted(callbacks)} />
                <button onClick={() => this.changeCow()} />
            </div>
        )
    }

    cowMounted (callbacks) {
        this.cowCallbacks = callbacks
    }

    changeCow () {
        this.cowCallbacks.say('moo')
    }

}

我没有测试过这个确切的代码,但是这与我在我的项目中所做的一致,并且它工作得很好:)。当然这是一个不好的例子,你应该只使用道具,但在我的情况下,子组件做了一个API调用,我想保留在该组件内。在这种情况下,这是一个很好的解决方案。


14
投票

你可以这样做

import React from 'react';

class Header extends React.Component{

    constructor(){
        super();
        window.helloComponent = this;
    }

    alertMessage(){
       console.log("Called from outside");
    }

    render(){

      return (
      <AppBar style={{background:'#000'}}>
        Hello
      </AppBar>
      )
    }
}

export default Header;

现在,从这个组件的外部,你可以这样调用如下

window.helloComponent.alertMessage();

3
投票

使用render方法可能会弃用返回值,建议的方法是将回调引用附加到根元素。像这样:

ReactDOM.render( <Hello name="World" ref={(element) => {window.helloComponent = element}}/>, document.getElementById('container'));

然后我们可以使用window.helloComponent访问它,并且可以使用window.helloComponent.METHOD访问它的任何方法。

这是一个完整的例子:

var onButtonClick = function() {
  window.helloComponent.alertMessage();
}

class Hello extends React.Component {
  alertMessage() {
    alert(this.props.name);
  }

  render() {
    return React.createElement("div", null, "Hello ", this.props.name);
  }
};

ReactDOM.render( <Hello name="World" ref={(element) => {window.helloComponent = element}}/>, document.getElementById('container'));
<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="container"></div>
<button onclick="onButtonClick()">Click me!</button>

2
投票

您可以使用函数将onClick处理程序添加到div(onClick是React自己的onClick实现),您可以在{ }花括号内访问该属性,并显示警告消息。

如果您希望定义可以在组件类上调用的静态方法 - 您应该使用静态。虽然:

“在此块中定义的方法是静态的,这意味着您可以在创建任何组件实例之前运行它们,并且这些方法无法访问组件的道具或状态。如果要在静态中检查props的值方法,让调用者传入props作为静态方法的参数。“ (source

一些示例代码:

    const Hello = React.createClass({

        /*
            The statics object allows you to define static methods that can be called on the component class. For example:
        */
        statics: {
            customMethod: function(foo) {
              return foo === 'bar';
            }
        },


        alertMessage: function() {
            alert(this.props.name);                             
        },

        render: function () {
            return (
                <div onClick={this.alertMessage}>
                Hello {this.props.name}
                </div>
            );
        }
    });

    React.render(<Hello name={'aworld'} />, document.body);

希望这对你有所帮助,因为我不知道我是否理解你的问题,所以如果我解释错了就纠正我:)


2
投票

似乎静态不推荐使用,而使用render公开某些函数的其他方法似乎也很复杂。与此同时,this Stack Overflow answer about debugging React虽然看似hack-y,却为我做了这份工作。


1
投票

如果您在ES6中,只需在您的示例中使用“static”关键字,例如:static alertMessage: function() { ...
},

希望可以帮助那里的任何人:)


0
投票
class AppProvider extends Component {
  constructor() {
    super();

    window.alertMessage = this.alertMessage.bind(this);
  }

  alertMessage() {
    console.log('Hello World');
 }
}

您可以使用window.alertMessage()从窗口中调用此方法。

© www.soinside.com 2019 - 2024. All rights reserved.