Reactjs 如何处理对话框组件外部的对话框状态?
我有以下对话框组件:Reactjs 如何处理对话框组件外部的对话框状态?,reactjs,Reactjs,我有以下对话框组件: class LoginDialog extends React.Component { state = { open: false, }; openDialog = () => { this.setState({ open: true }); }; handleClose = () => { this.setState({ open: false }); }; render() { return
class LoginDialog extends React.Component {
state = {
open: false,
};
openDialog = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false });
};
render() {
return (
<div>
<Dialog
open={this.state.open}
onClose={this.handleClose}
>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
Cancel
</Button>
<Button onClick={this.handleClose} color="primary">
Subscribe
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
classlogindialog扩展了React.Component{
状态={
开:错,
};
openDialog=()=>{
this.setState({open:true});
};
handleClose=()=>{
this.setState({open:false});
};
render(){
返回(
取消
订阅
);
}
}
如何从父组件打开该对话框并确保“关闭”对话框也可以工作?这是我的尝试
class MainAppBar extends React.Component {
state = {
openLoginDialog: false,
openRegisterDialog: false
};
render() {
return (
<div>
<Button color="inherit" onClick={this.state.openLoginDialog}>Login</Button>
)}
<LoginDialog /*not sure how to pass here openLoginDialog*//>
</div>
);
}
}
类MainAppBar扩展了React.Component{
状态={
openLoginDialog:错误,
openRegisterDialog:false
};
render(){
返回(
登录
)}
);
}
}
因此,我不确定是否必须在子/父级中保留对话框状态,以及如何从父级正确打开它。您可以在MainAppBar组件中定义handleClose()或等效的事件处理程序,并将其传递给子级。它可以管理父级上的状态变量(真/假),并将该布尔值传递到LoginDialog栏,以确定它们是否应该打开。这样子级的状态将由父级管理
class MainAppBar extends React.Component {
state = {
openLoginDialog: false,
openRegisterDialog: false
};
toggleDialog = () => {
this.setState((prevState) => {
return{
openLoginDialog: !prevState.openLoginDialog
}
})
}
render() {
return (
<div>
<Button color="inherit" onClick={this.state.openLoginDialog}>Login</Button>
)}
<LoginDialog open={this.state.openLoginDialog} toggle={this.toggleDialog}/>
</div>
);
}
}
类MainAppBar扩展了React.Component{
状态={
openLoginDialog:错误,
openRegisterDialog:false
};
切换对话框=()=>{
this.setState((prevState)=>{
返回{
openLoginDialog:!prevState.openLoginDialog
}
})
}
render(){
返回(
登录
)}
);
}
}
然后:
classlogindialog扩展了React.Component{
render(){
返回(
this.props.toggle}//不确定此侦听器的功能,但我假设您要关闭它
>
this.props.toggle}color=“primary”>
取消
this.props.toggle}color=“primary”>
订阅
);
}
}
如果让父组件管理对话框的状态,则可以允许它完全控制对话框,同时将控制功能传递给对话框元素本身:
class MainAppBar extends React.Component {
constructor(props) {
this.state = {
openLoginDialog: false,
openRegisterDialog: false
};
}
closeDialog() { // This method will be passed to the dialog component
this.setState({
openLoginDialog: false
});
}
render() {
return (
<div>
<Button color="inherit" onClick={this.state.openLoginDialog}>Login</Button>
)}
<LoginDialog isOpen={this.state.openLoginDialog} closeDialog={this.closeDialog}>
</div>
);
}
}
类MainAppBar扩展了React.Component{
建造师(道具){
此.state={
openLoginDialog:错误,
openRegisterDialog:false
};
}
closeDialog(){//此方法将被传递给对话框组件
这是我的国家({
openLoginDialog:错误
});
}
render(){
返回(
登录
)}
);
}
}
classlogindialog扩展了React.Component{
render(){
返回(
取消
订阅
);
}
}
无论登录对话框在父级中是否打开,您都必须保持该状态。将打开/关闭状态传递给子级,并通过道具将关闭对话框的回调传递给子级
class MainAppBar extends React.Component {
state = {
openLoginDialog: false,
openRegisterDialog: false
};
openLoginDialog = () => {
this.setState({
openLoginDialog: true
});
};
closeLoginDialog = () => {
this.setState({
openLoginDialog: false
});
};
render() {
return (
<div>
<Button color="inherit" onClick={() => this.openLoginDialog()}>
Login
</Button>
)}
<LoginDialog
closeLoginDialog={this.closeLoginDialog}
isLoginDialogOpen={this.state.openLoginDialog}
/>
</div>
);
}
}
类MainAppBar扩展了React.Component{
状态={
openLoginDialog:错误,
openRegisterDialog:false
};
openLoginDialog=()=>{
这是我的国家({
openLoginDialog:对
});
};
closeLoginDialog=()=>{
这是我的国家({
openLoginDialog:错误
});
};
render(){
返回(
this.openLoginDialog()}>
登录
)}
);
}
}
这个组件不需要任何状态管理,因为我们在父级中管理它。我们可以通过这种方式使产品变得纯净:
const LoginDialog = props => (
<div>
<Dialog open={props.isLoginDialogOpen} onClose={props.closeLoginDialog}>
<DialogActions>
<Button onClick={props.closeLoginDialog} color="primary">
Cancel
</Button>
<Button onClick={props.closeLoginDialog} color="primary">
Subscribe
</Button>
</DialogActions>
</Dialog>
</div>
);
const LoginDialog=props=>(
取消
订阅
);
希望这是有帮助的 我将采取与其他答案不同的方法,只在需要时包含
LoginDialog
现在,我们可以将LoginDialog
作为一个功能组件,并添加到Parent
组件。现在,我们的LoginDialog
更简单、更易于测试,并且不依赖于任何东西
class Parent extends React.Component {
state = {
isOpen: false,
};
// No need to use open and close handler because if the modal
// is open another execute of the function will close it
// this way we can still toggle it from the button that's opening the Dialog
toggleDialog = () => {
this.setState(prevState => ({
open: !prevState.open,
}));
};
// if you want make the handler more flexible you can write it like this
// make it a toggle by default with an optional nextState to
// make it more flexible
dialogStateHandler = (nextState) => () => {
this.setState(prevState => ({
open: nextState || !prevState.open,
}));
};
// to use this handler you will need to invoke it and passing
// in the nextState or without to make it toggle
// onClick={this.dialogStateHandler(true / false || without args to toggle)}
render() {
const { isOpen } = this.state;
return (
<div>
<button onClick={this.toggleDialog}>Toggle</button>
{/* include the Dialog component only when its open */}
{isOpen && <LoginDialog closeDialog={this.toggleDialog} />}
</div>
);
}
}
可以在父组件中管理对话框的可见性状态,并将控制对话框的函数作为属性传递给子组件。然后可以从子元素和父元素控制它。
const LoginDialog = props => (
<div>
<Dialog open={props.isLoginDialogOpen} onClose={props.closeLoginDialog}>
<DialogActions>
<Button onClick={props.closeLoginDialog} color="primary">
Cancel
</Button>
<Button onClick={props.closeLoginDialog} color="primary">
Subscribe
</Button>
</DialogActions>
</Dialog>
</div>
);
class Parent extends React.Component {
state = {
isOpen: false,
};
// No need to use open and close handler because if the modal
// is open another execute of the function will close it
// this way we can still toggle it from the button that's opening the Dialog
toggleDialog = () => {
this.setState(prevState => ({
open: !prevState.open,
}));
};
// if you want make the handler more flexible you can write it like this
// make it a toggle by default with an optional nextState to
// make it more flexible
dialogStateHandler = (nextState) => () => {
this.setState(prevState => ({
open: nextState || !prevState.open,
}));
};
// to use this handler you will need to invoke it and passing
// in the nextState or without to make it toggle
// onClick={this.dialogStateHandler(true / false || without args to toggle)}
render() {
const { isOpen } = this.state;
return (
<div>
<button onClick={this.toggleDialog}>Toggle</button>
{/* include the Dialog component only when its open */}
{isOpen && <LoginDialog closeDialog={this.toggleDialog} />}
</div>
);
}
}
const LoginDialog = ({ closeDialog }) => (
<div>
<Dialog
closeDialog={closeDialog}
>
<DialogActions>
<Button onClick={closeDialog} color="primary">
Cancel
</Button>
<Button onClick={closeDialog} color="primary">
Subscribe
</Button>
</DialogActions>
</Dialog>
)}
</div>
);