从外部调用React组件方法

76 reactjs

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

例如,在这个jsfiddle https://jsfiddle.net/r6r8cp3z/我想alertMessageHelloElement引用中调用该方法.

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

编辑(从JSFiddle复制代码)

<div id="container"></div>
<button onclick="onButtonClick()">Click me!</button>
Run Code Online (Sandbox Code Playgroud)
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')
);
Run Code Online (Sandbox Code Playgroud)

Jef*_*ley 50

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

你需要在返回时调用函数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'));
Run Code Online (Sandbox Code Playgroud)

然后呢HelloRendered.alertMessage().

  • 请注意,使用render的返回值被视为已弃用,并且预计将在以后的版本中删除以启用性能增强.获得对组件实例对象的引用的支持方法是添加属性`ref`,该属性是以实例作为参数调用的函数.这也允许您访问不在顶层的对象,例如,如果您正在渲染`<MuiThemeProvider> <Hello ref = {setHelloRef} /> </ MuiThemeProvider>`您获得了传递给`setHelloRef`的正确引用函数而不是一个'MuiThemeProvider`. (10认同)

Kus*_*ain 23

你可以这样做

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;
Run Code Online (Sandbox Code Playgroud)

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

window.helloComponent.alertMessage();
Run Code Online (Sandbox Code Playgroud)

  • 如果“this”不存在,你将如何使用功能性反应来做到这一点? (4认同)
  • 添加全局变量不是一个好的解决方案。有关为何全局变量不好的更多信息,请访问:http://wiki.c2.com/?GlobalVariablesAreBad (3认同)
  • 谢谢你的投票!是的全局变量并不好,但这是解决问题的一种方法. (3认同)
  • 它有效,但如果同一页面上有多个相同的组件,它就不起作用。 (3认同)
  • 其实简单又实用!就像它应该是。它的简单性给我留下了深刻的印象;真的没有想过。如果您应该有越来越多的组件,这种方法可能不会那么好用。谢谢! (2认同)
  • 这正是我需要的实用且简单的解决方案,谢谢! (2认同)

git*_*rik 21

我做过这样的事情:

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

}
Run Code Online (Sandbox Code Playgroud)

然后在其他地方:

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

}
Run Code Online (Sandbox Code Playgroud)

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

  • 我想你的意思是'this.cowCallbacks.say('moo')` (4认同)

Aka*_*ash 15

React hook - useRef



const MyComponent = ({myRef}) => {
  const handleClick = () => alert('hello world')
  myRef.current.handleClick = handleClick
  return (<button onClick={handleClick}>Original Button</button>)
}

MyComponent.defaultProps = {
  myRef: {current: {}}
}

const MyParentComponent = () => {
  const myRef = React.useRef({})
  return (
    <>
      <MyComponent 
        myRef={myRef}
      />
      <button onClick={myRef.current.handleClick}>
        Additional Button
      </button>
    </>
  )
}
Run Code Online (Sandbox Code Playgroud)

祝你好运...

  • 非常有用,解决了我的问题 (2认同)

Bre*_*ody 5

由于该render方法可能不建议使用返回值,因此建议的方法是将回调引用附加到根元素。像这样:

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

我们可以使用window.helloComponent进行访问,并且可以使用window.helloComponent.METHOD访问其任何方法。

这是一个完整的示例:

ReactDOM.render( <Hello name="World" ref={(element) => {window.helloComponent = element}}/>, document.getElementById('container'));
Run Code Online (Sandbox Code Playgroud)
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'));
Run Code Online (Sandbox Code Playgroud)