我需要在父按钮的子组件中启动一个函数,但是我没有它,有人知道某种形式,我已经看过一些例子但我找不到可以帮助我的东西,因为他们只处理属性更改
这是我的代码 父母:
import React from 'react';
import ReactDom from 'react-dom';
import AppBar from 'material-ui/AppBar';
import injectTapEventPlugin from 'react-tap-event-plugin';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Menux from '../componentes/menux';
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<AppBar
title="Aqui empezara todo"
onLeftIconButtonTouchTap = {Menuxr.handleToggle}
/>
<Menux />
</div>
);
}
}
injectTapEventPlugin();
ReactDom.render( <MuiThemeProvider><App/></MuiThemeProvider>,document.getElementById('workspace'));
孩子
import React from 'react';
import Drawer from 'material-ui/Drawer';
import AppBar from 'material-ui/AppBar';
import MenuItem from 'material-ui/MenuItem';
import RaisedButton from 'material-ui/RaisedButton';
export default class Menux extends React.Component {
constructor(props) {
super(props);
this.state = {openmenu: false};
}
handleClose = () => this.setState({openmenu: false});
handleToggle = () => this.setState({openmenu: !this.state.openmenu});
render() {
return (
<div>
<RaisedButton
label="Toggle Drawer"
ref="menu"
onTouchTap={this.handleToggle}/>
<Drawer width={200} openSecondary={false} open={this.state.openmenu} >
<AppBar title="menu"
onLeftIconButtonTouchTap = {this.handleClose}
/>
<MenuItem onTouchTap={this.handleClose}>Mi perfil</MenuItem>
<MenuItem onTouchTap={this.handleClose}>Mis usuarios</MenuItem>
<MenuItem onTouchTap={this.handleClose}>Mis unidades</MenuItem>
</Drawer>
</div>
);
}
答案 0 :(得分:5)
不幸的是,这并不是React的功能。您正试图Menux.handleToggle
作为onLeftIconButtonTouchTap
道具的回调,对吧?因此,当有人点击左侧图标按钮时,您希望Menux
组件执行handleToggle
功能吗?
这不会有两个原因:
1)当你拨打Menux.handleToggle
时,你没有在实例上调用它! Menux
是对类本身的引用。它没有您期望的内部状态。而且,handleToggle
是一种实例方法。这意味着它只能在Menux
类的实例上执行。
2)您可能正在引用Menux
类,但如上所述,这与React在呈现<Menux />
元素时创建的实例不同。
很难充分阐明为什么这是错误的,只是在几个层面上根本就是错误的嘿嘿。简而言之:您无法调用类这样的类的功能,并期望它更改未指定的类的实例。
让我们走过那条路。现在,有一种令人费解的方式让你的代码以你编写的方式工作,但我认为最好帮助你理解一种更惯用的方式。也就是说,更多的“反应方式”可以完成您想要的任务。
我们希望“举起国家”。这个概念是这篇文章: https://facebook.github.io/react/docs/lifting-state-up.html
我强烈建议您阅读该文章。
为什么我们“举起状态?”在React中,子节点不会相互通信。只有孩子和父母互相沟通。事实上,父母通过提供数据和功能进行交流,孩子只通过调用父母给他们的功能进行交流。
想象一下,你是一个孩子,是5个兄弟姐妹中的一个。你们每个人都有一部手机,但你不知道兄弟姐妹的电话号码。您只有父母的电话号码。但是你需要向你的一些兄弟姐妹传达一些信息。你是做什么?你打电话给你父母的电话号码,转发他们的信息,父母会打电话给你的兄弟姐妹并将数据转发给他们。
这就是React的工作原理。
那么我们如何将这个应用到你的情况呢?当菜单打开时,让我们让菜单告诉菜单。这样,父母可以为Menux
组件和AppBar
组件提供一个功能,他们可以用它来说“嘿妈妈,你可以关闭菜单吗?”
我们将状态从Menux组件提升到App组件。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
openmenu: false
}
}
handleClose = () => this.setState({openmenu: false});
handleToggle = () => this.setState({openmenu: !this.state.openmenu});
render() {
return (
<div>
<AppBar
title="Aqui empezara todo"
onLeftIconButtonTouchTap = {this.handleToggle}
/>
<Menux openmenu={this.state.openmenu} handleToggle={this.handleToggle} handleClose={this.handleClose} />
</div>
);
}
}
啊哈哈!现在,我们的应用程序确定菜单何时关闭以及何时不关闭。这是真理的唯一来源!但是,如果他们想要更改父级中的状态,它会为AppBar
和Menux
提供一些可以调用的函数。那么Menux
将如何改变?
export default class Menux extends React.Component {
render() {
return (
<div>
<RaisedButton
label="Toggle Drawer"
ref="menu"
onTouchTap={this.props.handleToggle}/>
<Drawer width={200} openSecondary={false} open={this.props.openmenu} >
<AppBar title="menu"
onLeftIconButtonTouchTap = {this.props.handleClose}
/>
<MenuItem onTouchTap={this.props.handleClose}>Mi perfil</MenuItem>
<MenuItem onTouchTap={this.props.handleClose}>Mis usuarios</MenuItem>
<MenuItem onTouchTap={this.props.handleClose}>Mis unidades</MenuItem>
</Drawer>
</div>
);
}
它使用父传递它的函数来设置父级中的状态。一个漂亮,简单,可重复使用的组件!
这是React的做事方式。只有亲子的沟通,状态和功能传递给孩子,孩子们称这些功能在树中更高的状态。美丽!
“但是,但是......我真的不想做React方式!”
Fiiiiine 。值得庆幸的是,其他人以一种非常简单的方式回答(所以我没有:]),无需重新构建您的应用程序 ahem 更为惯用的方式。 / p>
答案 1 :(得分:2)
使用ref
来保留对子组件的引用,以便您可以根据需要从父级调用handleToggle
:
<Menux ref={(menu)=>{this.menu = menu}}/>
然后:
<AppBar
title="Aqui empezara todo"
onLeftIconButtonTouchTap = {this.menu.handleToggle}
/>
答案 2 :(得分:0)
import React, { forwardRef, useRef, useImperativeHandle } from 'react';
export default function ParentFunction() {
const childRef = useRef();
return (
<div className="container">
<div>
Parent Component
</div>
<button
onClick={() => { childRef.current.showAlert() }}
>
Call Function
</button>
<Child ref={childRef}/>
</div>
)
}
const Child = forwardRef((props, ref) => {
useImperativeHandle(
ref,
() => ({
showAlert() {
alert("Child Function Called")
}
}),
)
return (
<div>Child Component</div>
)
})