我们说我有以下反应代码。
<Navigation parentWindow={this} />
<p>Sub Pages</p>
<ReactCSSTransitionGroup
component="div"
transitionName="page-transition"
transitionEnterTimeout={0}
transitionLeaveTimeout={500}
>
{React.cloneElement(this.props.children, {
key: location.pathname
})}
</ReactCSSTransitionGroup>
ReactCSSTransitionGroup
最终将呈现由<ContactPage />
创建的ContactPage.js
。这是ContactPage.js
的样子:
import React from 'react';
export default class Page extends React.Component
{
testMe() {alert('Hello World!');}
render() {return <div>Hello</div>;}
}
从<Navigation />
创建的Navigation.js
,我希望能够触发ContactPage.testMe()
。所以我在Navigation.js
import React from 'react';
export default class Page extends React.Component
{
render() {
this.props.parentWindow.props.children.testMe();
return <div>Navigate me</div>;
}
}
但是当我运行项目时,我的导航给了我错误:
Uncaught TypeError: this.props.parentWindow.props.children.testCall
如何解决这个问题?
答案 0 :(得分:1)
理论上,您可以使用refs
来实现此目的。在ParentWindow组件中,您将为克隆的子项分配一个ref
,然后您将其作为道具传递给导航。
React与其他JS库有点不同,它会强制您将业务逻辑或事件逻辑移动到父组件并将其作为props传递给它。我建议你将一个回调函数传递给Navigation页面,当它被触发时它会调用ContactPage方法。
class Navigation extends React.Component {
render() {
this.props.onAlertParent();
return <div>Navigate me</div>;
}
}
class ParentWindow extends Component {
alertChild() {
if (this.childNode && this.childNode.testMe) {
this.childNode.testMe();
}
}
render() {
<div>
<Navigation onAlertParent={() => this.alertChild()} />
<p>Sub Pages</p>
<ReactCSSTransitionGroup
component="div"
transitionName="page-transition"
transitionEnterTimeout={0}
transitionLeaveTimeout={500}
>
{React.cloneElement(this.props.children, {
key: location.pathname,
ref: (node) => { this.childNode = node; }
})}
</ReactCSSTransitionGroup>
</div>
}
}
注意Navigation
组件如何通过props接收回调函数,导航元素不需要知道有关其兄弟姐妹的任何信息,它使用父语件与它们进行通信。
反应方式是通过传递数据或回调使用props在组件之间进行通信。总是有一种比调用元素方法更好的通信方式。即使我建议的方法是有缺陷的,因为它仍然从元素中调用方法。