Sou*_*osh 0 javascript reactjs material-ui
我试图从父组件中的按钮单击事件调用子组件中的函数。
父组件:
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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,父组件在单击按钮时呈现子组件模式对话框(基于 Material-UI)。“保存”按钮是Dialog父组件中组件的一部分,单击时应调用Child组件中的保存函数。如您所见,我handleSaveDialog通过Child名为 的组件 props传递了一个回调函数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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我使用访问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
它不会工作,因为如果你控制台登录this.handleSaveClick功能render,它将是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>
);
}
Run Code Online (Sandbox Code Playgroud)
class Child extends Component {
componentDidMount() {
console.log("mount");
this.props.handleSaveData(this.handleSaveClick);
}
handleSaveClick = () => {
console.log("save clicked");
};
render() {
return <div>//..</div>;
}
}
Run Code Online (Sandbox Code Playgroud)
ref。链接: https: //codesandbox.io/s/musing-kalam-nj29nconst 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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
class Child extends Component {
handleSaveClick = () => {
console.log("save clicked");
};
render() {
return <div>//..</div>;
}
}
Run Code Online (Sandbox Code Playgroud)
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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
class Child extends Component {
componentDidMount() {
console.log("mount");
this.props.handleSaveData(this.handleSaveClick);
}
handleSaveClick = () => {
console.log("save clicked");
};
render() {
return <div>//..</div>;
}
}
Run Code Online (Sandbox Code Playgroud)
您将需要使用箭头函数,onClick因为每次我们单击时它都会创建一个新函数,从而获得 的新实例handleClick。如果你通过了,this.handleClick它就不起作用,因为它是undefined。this.handleClick您可以通过记录函数中的值来检查这一点render。
注:使用该2选项更可靠。
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
4644 次 |
| 最近记录: |