I have a class component that is a header-bar and when you click on an icon a dialog-box pop up where you can input data and save it. I am trying to split these two items- header-bar and dialog-box into two different components. Is the best way to do this to redirect the from the header-bar component to a new dialog-box component. At the moment i have both of them in one component.Thanks for the advice.
const{classes} = this.props
return (
<div>
<Dialog
open={this.state.open}
onClose={this.handleClose}
aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">Add Folder</DialogTitle>
<DialogContent>
<TextField
margin="normal"
onChange={this.handleChange('name')}
/>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
Cancel
</Button>
<Button onClick={this.handleClose} color="primary"
onChange={this.handleFieldChange}
value={this.state.value}>
Create
</Button>
</DialogActions>
</Dialog>
<AppBar position="static" className={classes.bar} >
<Toolbar>
<IconButton color="inherit" aria-label="createfolder">
<SvgIcon>
<path d={createfolder}
onClick={this.handleClickOpen}
name="firstName"/>
</SvgIcon>
</IconButton>
</Toolbar>
</AppBar>
</div>
);
No, the best way to do this is not to redirect but same way, in a more modular or component/react way. You can create a functional component of dialog box and include it in your main component,
In the below code the functional component has been made inside the main component class itself so it can access the this.
DialogBox = ({state}) =>(
<Dialog
open={state.open}
onClose={this.handleClose}
aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">Add Folder</DialogTitle>
<DialogContent>
<TextField
margin="normal"
onChange={this.handleChange('name')}
/>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
Cancel
</Button>
<Button onClick={this.handleClose} color="primary"
onChange={this.handleFieldChange}
value={state.value}>
Create
</Button>
</DialogActions>
</Dialog>
)
Now include this in your header-bar component,
const{classes} = this.props
return (
<div>
<AppBar position="static" className={classes.bar} >
<Toolbar>
<IconButton color="inherit" aria-label="createfolder">
<SvgIcon>
<path d={createfolder}
onClick={this.handleClickOpen}
name="firstName"/>
</SvgIcon>
</IconButton>
</Toolbar>
</AppBar>
<this.DialogBox state={this.state}/>
</div>
);
Related
I've got some problem with omit re-render while click button which open Dialog component. Currently I use useState flag which toggle my Dialog component but I must avoid re-rendering because there's expensive operations on big data.
Anyone know approach how to Open Dialog by button Open and Close Dialog by click on Dialog's button Exit.
const Item = () => {
const popupRef = useRef()
const dialog = () => {
return(
<Dialog ref={popupRef}
keepMounted
fullWidth
maxWidth="md"
aria-labelledby="alert-dialog-slide-title"
aria-describedby="alert-dialog-slide-description">
<DialogTitle id="alert-dialog-slide-title">
<WrapperDialogHeader>Filters</WrapperDialogHeader>
<WrapperDialogCloseBtn>
<IconButton aria-label="close" >
<CloseIcon />
</IconButton>
</WrapperDialogCloseBtn>
</DialogTitle>
<DialogContent>
Something
</DialogContent>
<DialogActions>
<Button variant="outlined"
// onClick={ What handler here? }
color="primary">
<WrapperDialogOptionBtn>Exit</WrapperDialogOptionBtn>
</Button>
</DialogActions>
</Dialog>
)
}
return(
<>
<IconButton onClick={ /* What method here */ }>
<Typography variant="body1" color="primary">
<FilterListIcon fontSize="small" color="primary"/><WrapperFontSpecialSmall>Filters</WrapperFontSpecialSmall>
</Typography>
</IconButton>
{ dialog() }
</>
Methods like popupRef.current.click() not exist in ES6 I suppose.
How to build mechanism which toggle dialog without re-render whole component Item.
Move the dialog to its own component and wrap in memo()
const Dialog = ({ open, onClose }) => {
return (
<Dialog
keepMounted // why? you said the content is huge, so why keep it mounted
fullWidth
maxWidth="md"
aria-labelledby="alert-dialog-slide-title"
aria-describedby="alert-dialog-slide-description"
open={open}
onClose={onClose}
>
<DialogTitle id="alert-dialog-slide-title">
<WrapperDialogHeader>Filters</WrapperDialogHeader>
<WrapperDialogCloseBtn>
<IconButton aria-label="close" >
<CloseIcon />
</IconButton>
</WrapperDialogCloseBtn>
</DialogTitle>
<DialogContent>
Something
</DialogContent>
<DialogActions>
<Button variant="outlined" onClick={onClose} color="primary">
<WrapperDialogOptionBtn>Exit</WrapperDialogOptionBtn>
</Button>
</DialogActions>
</Dialog>
)
};
export default memo(Dialog); // IMPORTANT
In the Item component,
const Item = () => {
const [dialogOpen, setDialogOpen] = useState(false);
const handleDialogOpen = () => setDialogOpen(true);
// prevent function being recreated on state change
const handleDialogClose = useCallback(() => setDialogOpen(false), []);
return (
<>
<IconButton onClick={handleDialogOpen}>
<Typography variant="body1" color="primary">
<FilterListIcon fontSize="small" color="primary" /><WrapperFontSpecialSmall>Filters</WrapperFontSpecialSmall>
</Typography>
</IconButton>
<Dialog open={dialogOpen} onClose={handleDialogClose} />
</>
);
}
Sidenote, it appears the dialog contains some sort of filter UI, presumably one or more lists. You may want to have a look at react-window if you are going to create long lists.
I have a page with a modal window. In development mode, it opens. But when I upload my React App to vercel, then the screen just darkens there, and the modal window does not appear, but all the window controls work. Who faced the same problem?
const { isOpen, onOpen, onClose } = useDisclosure()
return (
<>
<Button onClick={onOpen}>Open Modal</Button>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Lorem count={2} />
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Close
</Button>
<Button variant="ghost">Secondary Action</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
)
I was able to fix this by upgrading the "framer-motion": version -> "framer-motion": "^4.1.16".
I am using the component "Dialog" from Material UI.
When I click on the button to close the Dialog (which triggers handleCLose), it does not set the state to false.
I read a similar problem here: OnClick Listeners not working after closing full-screen dialog using react-material-ui
but I have not managed to save it so far.
const Transition = React.forwardRef(function Transition(props, ref) {
return <Slide direction="up" ref={ref} {...props} />;
});
function Information() {
const [open, setOpen] = React.useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
console.log(open)
};
return (
<div onClick={()=>handleClickOpen()}>
Information
<Dialog
open={open}
TransitionComponent={Transition}
keepMounted
onClose={handleClose}
aria-labelledby="alert-dialog-slide-title"
aria-describedby="alert-dialog-slide-description"
>
<DialogTitle id="alert-dialog-slide-title">{"Information"}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-slide-description">
Blablabla
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary"> // The function is here
Close
</Button>
</DialogActions>
</Dialog>
</div>
);
}
export default Information
It looks like you have wrapped your dialog in a div with an onClick function that sets the dialog to open. What is happening is that onClick is being called whenever you click inside the dialog. So even when you click the close button it is calling handleClickOpen. Try separating them:
return (
<> // Add wrapping fragment
<div onClick={()=>handleClickOpen()}>
Information
</div> // close div here
<Dialog
open={open}
TransitionComponent={Transition}
keepMounted
onClose={handleClose}
aria-labelledby="alert-dialog-slide-title"
aria-describedby="alert-dialog-slide-description"
>
<DialogTitle id="alert-dialog-slide-title">{"Information"}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-slide-description">
Blablabla
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary">
Close
</Button>
</DialogActions>
</Dialog>
</>
);
}
I'm trying to use material-ui checkbox inside dialog but onChange function seems not working. Please refer the following info for my code:
<Dialog open={showAssetListDialog}>
<DialogTitle id="responsive-dialog-title">
<h3 className="formHeader">Asset List</h3>
<hr />
</DialogTitle>
<DialogContent>
<Typography>
{ availableAssets && Object.keys(assetList).map((key, index) => (
<p>
<Checkbox
const asset_id = {assetList[index].value}
checked = {assetList[index].asset_id}
color = "primary"
onChange = {props.handleCheckboxChange('asset_id')}
onCheck = {props.handleCheckboxChange}
>
</Checkbox>
{assetList[index].label}
</p>
))}
</Typography>
</DialogContent>
<DialogActions>
<Button
color="success"
className="btnSave"
onClick={props.handleAssetListClose}
>
Done
</Button>
</DialogActions>
</Dialog>
I am trying to use MUI readymade components in my react application,
I import everything correctly, after all these when I am running the app, there is the only element shows in the browser, not its style.
import React, { Component } from 'react';
import Button from '../node_modules/muicss/lib/react/button';
class App extends Component {
render() {
return (
<div>
<div>
<Button size="small" color="primary">button</Button>
<Button size="small" color="primary" variant="flat">button</Button>
<Button size="small" color="primary" variant="raised">button</Button>
<Button size="small" color="primary" variant="fab">+</Button>
</div>
<div>
<Button color="primary">button</Button>
<Button color="primary" variant="flat">button</Button>
<Button color="primary" variant="raised">button</Button>
<Button color="primary" variant="fab">+</Button>
</div>
<div>
<Button size="large" color="primary">button</Button>
<Button size="large" color="primary" variant="flat">button</Button>
<Button size="large" color="primary" variant="raised">button</Button>
<Button size="large" color="primary" variant="fab">+</Button>
</div>
</div>
);
}
}
export default App;
You dont need to set the exact path for node_modules just type the component name for importing any component.
Like below import statement in material ui doc.
import Button from '#material-ui/core/Button';