如何在 ReactJS 中从“外部”访问组件方法?
Posted
技术标签:
【中文标题】如何在 ReactJS 中从“外部”访问组件方法?【英文标题】:How to access component methods from “outside” in ReactJS? 【发布时间】:2014-09-10 14:04:28 【问题描述】:为什么我不能从 ReactJS 的“外部”访问组件方法?为什么不可以,有什么办法可以解决吗?
考虑代码:
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);
【问题讨论】:
也许你需要Pubsub
?
【参考方案1】:
从 React 16.3 开始可以使用 React.createRef
,(使用 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)
【讨论】:
【参考方案2】:另一种如此简单的方法:
功能外:
function funx(functionEvents, params)
console.log("events of funx function: ", functionEvents);
console.log("this of component: ", this);
console.log("params: ", params);
thisFunction.persist();
绑定它:
constructor(props)
super(props);
this.state = ;
this.funxBinded = funx.bind(this);
请在此处查看完整教程:How to use "this" of a React Component from outside?
【讨论】:
【参考方案3】:React 通过ref
attribute 为您尝试执行的操作提供了一个接口。为组件分配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>
);
注意:这仅在子组件被声明为类时才有效,根据此处找到的文档:https://facebook.github.io/react/docs/refs-and-the-dom.html#adding-a-ref-to-a-class-component
2019 年 4 月 1 日更新: 根据最新的 React 文档将示例更改为使用类和 createRef
。
2016 年 9 月 19 日更新: 根据the ref
String attribute docs 的指导将示例更改为使用 ref 回调。
【讨论】:
那么,在两个子组件之间进行通信的唯一方法是同时拥有 refs 并通过公共父组件上的代理方法? React 鼓励数据驱动的组件。让一个孩子调用一个回调来更改其祖先中的数据,当该数据发生变化时,另一个孩子将获得新的props
并适当地重新渲染。
@RossAllen,哈哈,是的,在这种情况下,您也必须删除分号。
@HussienK 如果函数不应该有返回值,我更喜欢使用块,这样对于下一个阅读代码的开发人员来说意图是显而易见的。将其更改为 (child) => this._child = child
将创建一个始终返回 true
的函数,但 React 的 ref
属性不使用该值。【参考方案4】:
正如一些 cmets 中提到的,ReactDOM.render
不再返回组件实例。您可以在渲染组件的根目录时传入ref
回调以获取实例,如下所示:
// React code (jsx)
function MyWidget(el, refCb)
ReactDOM.render(<MyComponent ref=refCb />, el);
export default MyWidget;
和:
// vanilla javascript code
var global_widget_instance;
MyApp.MyWidget(document.getElementById('my_container'), function(widget)
global_widget_instance = widget;
);
global_widget_instance.myCoolMethod();
【讨论】:
【参考方案5】:你可以也这样做,不知道这是否是一个好计划: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)
【讨论】:
【参考方案6】:从 React 0.12 开始,API 是 slightly changed。初始化 myChild 的有效代码如下:
var Child = React.createClass(…);
var myChild = React.render(React.createElement(Child, ), mountNode);
myChild.someMethod();
【讨论】:
【参考方案7】:如果你想从 React 外部调用组件上的函数,你可以在 renderComponent 的返回值上调用它们:
var Child = React.createClass(…);
var myChild = React.renderComponent(Child);
myChild.someMethod();
在 React 之外获取 React 组件实例句柄的唯一方法是存储 React.renderComponent 的返回值。 Source.
【讨论】:
实际上它适用于 react16。 ReactDOM 渲染方法返回对组件的引用(或为无状态组件返回 null)。【参考方案8】:或者,如果 Child 上的方法是真正的静态方法(不是当前 props 和 state 的产物),您可以在 statics
上定义它,然后像访问静态类方法一样访问它。例如:
var Child = React.createClass(
statics:
someMethod: function()
return 'bar';
,
// ...
);
console.log(Child.someMethod()) // bar
【讨论】:
来源是here。以上是关于如何在 ReactJS 中从“外部”访问组件方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Material-UI、ReactJS 中从分页中设置分页项的样式?