简体   繁体   English

如何在 ReactJS 中从“外部”访问组件方法?

[英]How to access component methods from “outside” in ReactJS?

Why can't I access the component methods from “outside” in ReactJS?为什么我不能在 ReactJS 中从“外部”访问组件方法? Why is it not possible and is there any way to solve it?为什么不可能,有什么办法可以解决?

Consider the code:考虑代码:

var Parent = React.createClass({
    render: function() {
        var child = <Child />;
        return (
            <div>
                {child.someMethod()} // expect "bar", got a "not a function" error.
            </div>
        );
    }
});

var Child = React.createClass({
    render: function() {
        return (
            <div>
                foo
            </div>
        );
    },
    someMethod: function() {
        return 'bar';
    }
});

React.renderComponent(<Parent />, document.body);

React provides an interface for what you are trying to do via the ref attribute . React 通过ref属性为您尝试执行的操作提供了一个接口。 Assign a component a ref , and its current attribute will be your custom component:为组件分配一个ref ,其current属性将是您的自定义组件:

class Parent extends React.Class {
    constructor(props) {
        this._child = React.createRef();
    }

    componentDidMount() {
        console.log(this._child.current.someMethod()); // Prints 'bar'
    }

    render() {
        return (
            <div>
                <Child ref={this._child} />
            </div>
        );
    }
}

Note : This will only work if the child component is declared as a class, as per documentation found here: https://facebook.github.io/react/docs/refs-and-the-dom.html#adding-a-ref-to-a-class-component注意:这仅在子组件被声明为类时才有效,根据此处找到的文档: https : //facebook.github.io/react/docs/refs-and-the-dom.html#adding-a-引用到类组件

Update 2019-04-01: Changed example to use a class and createRef per latest React docs. 2019 年 4 月 1 日更新:更改了示例以根据最新的 React 文档使用类和createRef

Update 2016-09-19: Changed example to use ref callback per guidance from the ref String attribute docs. 2016 年 9 月 19 日更新:更改示例以根据ref String 属性文档中的指导使用 ref 回调。

If you want to call functions on components from outside React, you can call them on the return value of renderComponent:如果你想从 React 外部调用组件上的函数,你可以在 renderComponent 的返回值上调用它们:

var Child = React.createClass({…});
var myChild = React.renderComponent(Child);
myChild.someMethod();

The only way to get a handle to a React Component instance outside of React is by storing the return value of React.renderComponent.在 React 之外获取 React Component 实例句柄的唯一方法是存储 React.renderComponent 的返回值。 Source .来源

Alternatively, if the method on Child is truly static (not a product of current props, state) you can define it on statics and then access it as you would a static class method.或者,如果 Child 上的方法确实是静态的(不是当前道具、状态的产物),您可以在statics上定义它,然后像访问静态类方法一样访问它。 For example:例如:

var Child = React.createClass({
  statics: {
    someMethod: function() {
      return 'bar';
    }
  },
  // ...
});

console.log(Child.someMethod()) // bar

As of React 16.3 React.createRef can be used, (use ref.current to access)从 React 16.3 React.createRef可以使用ref.current ,(使用ref.current访问)

var ref = React.createRef()

var parent = (
  <div>
    <Child ref={ref} />
    <button onClick={e=>console.log(ref.current)}
  </div>
);

React.renderComponent(parent, document.body)

Since React 0.12 the API is slightly changed .从 React 0.12 开始,API 略有变化 The valid code to initialize myChild would be the following:初始化 myChild 的有效代码如下:

var Child = React.createClass({…});
var myChild = React.render(React.createElement(Child, {}), mountNode);
myChild.someMethod();

You could also do it like this, not sure if it's a good plan :D可以这样做,不确定这是否是一个好的计划:D

class Parent extends Component {
  handleClick() {
    if (this._getAlert !== null) {
      this._getAlert()
    }
  }

  render() {
    return (
      <div>
        <Child>
        {(getAlert, childScope) => (
          <span> {!this._getAlert ? this._getAlert = getAlert.bind(childScope) : null}</span>
        )}
        </Child>
        <button onClick={() => this.handleClick()}> Click me</button>
      </div>
      );
    }
  }

class Child extends Component {
  constructor() {
    super();
    this.state = { count: 0 }
  }

  getAlert() {
    alert(`Child function called state: ${this.state.count}`);
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return this.props.children(this.getAlert, this)
  }
}

As mentioned in some of the comments, ReactDOM.render no longer returns the component instance.正如一些评论中提到的, ReactDOM.render不再返回组件实例。 You can pass a ref callback in when rendering the root of the component to get the instance, like so:您可以在渲染组件的根目录时传入ref回调以获取实例,如下所示:

// React code (jsx)
function MyWidget(el, refCb) {
    ReactDOM.render(<MyComponent ref={refCb} />, el);
}
export default MyWidget;

and:和:

// vanilla javascript code
var global_widget_instance;

MyApp.MyWidget(document.getElementById('my_container'), function(widget) {
    global_widget_instance = widget;
});

global_widget_instance.myCoolMethod();

Another way so easy:另一个很简单的方法:

function outside:外功能:

function funx(functionEvents, params) {
  console.log("events of funx function: ", functionEvents);
  console.log("this of component: ", this);
  console.log("params: ", params);
  thisFunction.persist();
}

Bind it:绑定它:

constructor(props) {
   super(props);
    this.state = {};
    this.funxBinded = funx.bind(this);
  }
}

Please see complete tutorial here: How to use "this" of a React Component from outside?请在此处查看完整教程: 如何从外部使用 React 组件的“this”?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM