[英]Calling Child component function from Parent component in React.js
我试图从父组件中的按钮单击事件中调用子组件中的函数。
父组件:
class Parent extends Component{
constructor(props){
super(props);
this.state = {
//..
}
}
handleSaveDialog = (handleSaveClick) => {
this.handleSaveClick = handleSaveClick;
}
render(){
return(
<div>
<Button onClick={this.openDialog}>Open Dialog</Button>
<Dialog>
<DialogTitle id="form-dialog-title">Child Dialog</DialogTitle>
<DialogContent>
<Child handleSaveData={this.handleSaveDialog}/>
</DialogContent>
<DialogActions>
<Button onClick={this.handleSaveClick} color="primary">
Save
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
在上面的代码中,单击按钮后,父组件将呈现子组件模态对话框(基于Material-UI)。 单击“保存”按钮,即“父项”中“ Dialog
组件的一部分,应在“ Child
组件中调用保存功能。 正如你所看到的,我已经过了一个回调函数handleSaveDialog
通过Child
命名组件道具handleSaveData
。 一旦子组件安装并将回调传递给父组件,则单击保存按钮将在子组件上调用handleSaveClick
。
子组件:
class Child extends Component{
constructor(props){
super(props);
this.state = {
//..
}
}
componentDidMount(){
console.log('mount');
this.props.handleSaveData( () => this.handleSaveClick());
}
handleSaveClick = () => {
console.log('save clicked');
}
render(){
return(
<div>
//..
</div>
);
}
}
在上面的代码中,我正在使用访问Parent
组件props传递的回调函数,并将其绑定到Child
组件的save fucntion handleSaveClick
。
问题:
当我第一次单击“父项”中的“打开对话框”按钮时,该Dialog
安装“子项”组件。 但是,单击“ Save
按钮不起作用(没有错误)。 关闭对话框后,当我重新打开对话框并单击“保存”时,将触发“子”对话框中的handleSaveClick
,并在浏览器控制台中记录一条消息。 知道为什么第二次而不是第一次有效吗? 请记住,仅当我单击父组件上的“打开对话框”时,才会装入/加载子组件。
参考文献:
https://material-ui.com/components/dialogs/#form-dialogs
https://github.com/kriasoft/react-starter-kit/issues/909#issuecomment-390556015
好吧,我不知道为什么会有这种情况,但是我想到的第一件事就是可以在Parent组件中编写handleSaveClick
方法。 并且如果您需要在子组件中可能发生的任何操作上使用该函数,则可以将该函数作为父组件的prop传递。 所以你两种情况都可以处理
如果仍然认为您必须在子组件中定义方法,则可以使用refs
这将不起作用,因为如果您在render
函数中控制台登录this.handleSaveClick
,则将无法undefined
它,因为没有重新渲染。 因此,有两种方法可以实现:
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false
};
}
openDialog = () => {
this.setState(preState => ({
open: !preState.open
}));
};
handleSaveDialog = handleSaveRef => {
this.setState({
handleSaveClick: handleSaveRef
});
};
render() {
console.log("Render", this.handleSaveClick);
return (
<div>
<Button onClick={this.openDialog}>Open Dialog</Button>
<Dialog open={this.state.open}>
<DialogTitle id="form-dialog-title">Child Dialog</DialogTitle>
<DialogContent>
<Child handleSaveData={this.handleSaveDialog} />
</DialogContent>
<DialogActions>
<Button onClick={this.state.handleSaveClick} color="primary">
Save
</Button>
</DialogActions>
</Dialog>
</div>
);
}
class Child extends Component {
componentDidMount() {
console.log("mount");
this.props.handleSaveData(this.handleSaveClick);
}
handleSaveClick = () => {
console.log("save clicked");
};
render() {
return <div>//..</div>;
}
}
ref
。 链接: https : //codesandbox.io/s/musing-kalam-nj29n const childRef = React.createRef();
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false
};
}
openDialog = () => {
this.setState(preState => ({
open: !preState.open
}));
};
handleSaveClick = () => {
if (childRef.current) {
childRef.current.handleSaveClick();
}
};
render() {
return (
<div>
<Button onClick={this.openDialog}>Open Dialog</Button>
<Dialog open={this.state.open}>
<DialogTitle id="form-dialog-title">Child Dialog</DialogTitle>
<DialogContent>
<Child ref={childRef} />
</DialogContent>
<DialogActions>
<Button onClick={this.handleSaveClick} color="primary">
Save
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
class Child extends Component {
handleSaveClick = () => {
console.log("save clicked");
};
render() {
return <div>//..</div>;
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false
};
}
openDialog = () => {
this.setState(preState => ({
open: !preState.open
}));
};
handleSaveDialog = handleSaveRef => {
this.handleSaveClick = handleSaveRef;
};
render() {
return (
<div>
<Button onClick={this.openDialog}>Open Dialog</Button>
<Dialog open={this.state.open}>
<DialogTitle id="form-dialog-title">Child Dialog</DialogTitle>
<DialogContent>
<Child handleSaveData={this.handleSaveDialog} />
</DialogContent>
<DialogActions>
<Button onClick={() => this.handleSaveClick()} color="primary">
Save
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
class Child extends Component {
componentDidMount() {
console.log("mount");
this.props.handleSaveData(this.handleSaveClick);
}
handleSaveClick = () => {
console.log("save clicked");
};
render() {
return <div>//..</div>;
}
}
您将需要在onClick
使用箭头函数,因为每次我们单击它都会创建一个新函数,从而获得handleClick
的新实例。 而且如果您通过this.handleClick
它将无法使用,因为它是undefined
。 您可以通过在render
函数中记录this.handleClick
的值来进行检查。
注意:使用2
选项更加可靠。
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.