I have the following component:
<Stack direction="row" spacing={2}>
<Skeleton variant="rounded" animation="wave" sx={{ width: 1 }} />
<Loading
text="Loading..."
sx={{ position: 'relative', background: 'none', color: 'grey' }}
recommendedSolutions={
<LoadingBtn
onClick={refetch}
variant="outlined"
loadingIndicator="Refetching data..."
loading={loading}
>
Try again
</LoadingBtn>
}
/>
</Stack>
I want to be able to change the direction prop of the Stack component based on the screen breakpoint. The question is:
I can use the grid component to solve this problem as follows:
<Grid container>
<Grid item sx={{ display: { xs: 'none', md: 'block' } }}>
<Stack direction="row" spacing={2}>
<Skeleton variant="rounded" animation="wave" sx={{ width: 1 }} />
<Loading
text="Loading..."
sx={{ position: 'relative', background: 'none', color: 'grey' }}
recommendedSolutions={
<LoadingBtn
onClick={refetch}
variant="outlined"
loadingIndicator="Refetching data..."
loading={loading}
>
Try again
</LoadingBtn>
}
/>
</Stack>
</Grid>
<Grid item sx={{ display: { xs: 'block', md: 'none' } }}>
<Stack direction="vertical" spacing={2}>
<Skeleton variant="rounded" animation="wave" sx={{ width: 1 }} />
<Loading
text="Loading..."
sx={{ position: 'relative', background: 'none', color: 'grey' }}
recommendedSolutions={
<LoadingBtn
onClick={refetch}
variant="outlined"
loadingIndicator="Refetching data..."
loading={loading}
>
Try again
</LoadingBtn>
}
/>
</Stack>
</Grid>
</Grid>
but this makes me repeat similar code, is there a way I can do it within the direction prop of the Stack component itself? it's a tough task to write that much code
I am working on EDIT formik form, this form is in form of MODAL. when setState is passed as setState(true) than form will appear. But the problem is that without clicking onClick setState is being triggerd (according to error). In form values are already passed as it is EDIT form. I changed onClick={editStory} to onClick={()=> editStory()} still error not gone
Error: "Warning: Maximum update depth exceeded. This can happen when a
component calls setState inside useEffect, but useEffect either
doesn't have a dependency array, or one of the dependencies changes on
every render.
at EditQs (webpack-internal:///./src/new-components/Projects/EditQs.js:106:23)"
MyQs2.js
function MyQs2({row, isItemSelected, labelId, index}) {
const theme = useTheme();
const editStory = () => {
console.log('editstory is triggering')
setOpenStoryDrawer(true);
};
const [openStoryDrawer, setOpenStoryDrawer] = React.useState(false);
const handleStoryDrawerOpen = () => {
setOpenStoryDrawer(false);
};
const [allUsers, setAllUsers] = React.useState([])
const [allUsersObj, setAllUsersObj] = React.useState([])
const [allProjects, setAllProjects] = React.useState([])
//Error occur in this useEffect but i need updated data to show from firestore
React.
useEffect(() => {
readAllUsers()
readAllProjects()
}, [])
const readAllUsers = async()=> {
console.log('readAllUsesrs is calling')
try{
firebase.firestore().collection("users").where("role", "==", 'user')
.onSnapshot(function (val) {
let user = []
val.forEach(function(doc) {
user.push(doc.data().name);
setAllUsers(user)
})})
}
const readAllProjects = async() => {
console.log('readAllUsesrs is calling')
const snapshot = await firebase.firestore().collection('projects').get()
setAllProjects( snapshot.docs.map(doc => doc.data().name) );
}
return (
<>
<TableRow hover role="checkbox" aria-checked={isItemSelected} tabIndex={-1} key={index} selected={isItemSelected}>
<TableCell padding="checkbox" sx={{ pl: 3 }} onClick={(event) => handleClick(event, row.question)}>
<Checkbox
color="primary"
checked={isItemSelected}
inputProps={{
'aria-labelledby': labelId
}}
/>
</TableCell>
<TableCell
component="th"
id={labelId}
scope="row"
onClick={(event) => handleClick(event, row.projects)}
sx={{ cursor: 'pointer' }}
>
<Typography variant="subtitle1" sx={{ color: theme.palette.mode === 'dark' ? 'grey.600' : 'grey.900' }}>
{' '}
{row.question}{' '}
</Typography>
<Typography variant="caption"> {row.projects} </Typography>
</TableCell>
<TableCell>{row.projects}</TableCell>
<TableCell align="right">{row.assignTo}</TableCell>
<TableCell align="center">{row.priority}</TableCell>
<TableCell align="center">
{row.state === "published" && <Chip label="published" size="small" chipcolor="success" />}
{row.state === "unpublished" && <Chip label="unpublished" size="small" chipcolor="orange" />}
{row.state === 'Active' && <Chip label="Confirm" size="small" chipcolor="primary" />}
</TableCell>
<TableCell align="center" sx={{ pr: 3 }}>
<IconButton color="primary" size="large">
<VisibilityTwoToneIcon sx={{ fontSize: '1.3rem' }} />
</IconButton>
//below onClick is triggering
<IconButton color="secondary" size="large" onClick={()=> editStory()}
<EditTwoToneIcon sx={{ fontSize: '1.3rem' }} />
</IconButton>
</TableCell>
</TableRow>
// This calls a EditPage
<EditQs existingQs={row} open={openStoryDrawer} handleDrawerOpen={handleStoryDrawerOpen} allProjects={allProjects} allUsers={allUsers} />
</>
);
}
export default MyQs2
According to error appears in this Form page
EditQs.js
const EditQs = ({ open, handleDrawerOpen, existingQs, allProjects, allUsers }) => {
const dispatch = useDispatch();
const sendDataToFirestore = (item) => {
try{
firebase.firestore()
.collection('projects')
.doc(item.projects)
.update({
question : firebase.firestore.FieldValue.arrayUnion(item)
}).then(
dispatch(
openSnackbar({
open: true,
message: 'New Question added',
variant: 'alert',
alert: {
color: 'success'
},
close: false
})
)
)
}catch(err){
console.log('an error occured', err)
}
}
const formik = useFormik({
enableReinitialize: true, //if i remove this, error gone but this is responsible
for adding values in formik during render
validateOnChange:false,
validateOnBlur:false,
initialValues: {
id: existingQs.id ? existingQs.id : '',
question: existingQs.question? existingQs.question : '',
projects: existingQs.projects? existingQs.projects : '',
assignTo: existingQs.assignTo ? existingQs.assignTo : '',
priority: existingQs.priority ? existingQs.priority : '',
dueDate: existingQs.dueDate ? new Date(existingQs.dueDate) : new Date(),
state: existingQs.state ? existingQs.state : '',
image: existingQs.image
},
validationSchema,
onSubmit: (values,{resetForm}) => {
const item = {
id: values.id,
question: values.question,
projects: values.projects,
assignTo: values.assignTo,
priority: values.priority,
dueDate: values.dueDate ? new Date(values.dueDate) : new Date(),
state: values.state,
image: values.image
};
sendDataToFirestore(item);
() => handleDrawerOpen();
resetForm()
readAllProjects()
}
});
return (
<Drawer
sx={{
ml: open ? 3 : 0,
flexShrink: 0,
zIndex: 1200,
overflowX: 'hidden',
width: { xs: 320, md: 450 },
'& .MuiDrawer-paper': {
height: '100vh',
width: { xs: 320, md: 450 },
position: 'fixed',
border: 'none',
borderRadius: '0px'
}
}}
variant="temporary"
anchor="right"
open={open}
ModalProps={{ keepMounted: true }}
onClose={() => handleDrawerOpen}
>
{open && (
<Box sx={{ p: 3 }}>
<form onSubmit={formik.handleSubmit}>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Typography variant="h4">Edit Question</Typography>
</Grid>
<Grid item xs={12}>
<Grid container alignItems="center" spacing={2}>
<Grid item xs={12} sm={4}>
<Typography variant="subtitle1">Question:</Typography>
</Grid>
<Grid item xs={12} sm={8}>
<TextField
fullWidth
id="question"
name="question"
multiline
rows={3}
value={formik.values.question}
onChange={formik.handleChange}
error={formik.touched.question && Boolean(formik.errors.question)}
helperText={formik.touched.question && formik.errors.question}
/>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<Grid container alignItems="center" spacing={2}>
<Grid item xs={12} sm={4}>
<Typography variant="subtitle1">Assign to:</Typography>
</Grid>
<Grid item xs={12} sm={8}>
<FormControl fullWidth sx={{ m: 1 }}>
<InputLabel>Choose a user</InputLabel>
<Select
id="assignTo"
name="assignTo"
displayEmpty
value={formik.values.assignTo}
onChange={formik.handleChange}
label='Assign to'
inputProps={{ 'aria-label': 'assignTo' }}
>
{allUsers.map((val, index) => (
<MenuItem key={index} value={val}>
{val}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<Grid container alignItems="center" spacing={2}>
<Grid item xs={12} sm={4}>
<Typography variant="subtitle1">project:</Typography>
</Grid>
<Grid item xs={12} sm={8}>
<FormControl fullWidth sx={{ m: 1 }}>
<InputLabel>Choose a Project</InputLabel>
<Select
id="projects"
name="projects"
displayEmpty
value={formik.values.projects}
onChange={formik.handleChange}
label='projects'
inputProps={{ 'aria-label': 'projects' }}
>
{allProjects.map((val, index) => (
<MenuItem key={index} value={val}>
{val}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<Grid container alignItems="center" spacing={2}>
<Grid item xs={12} sm={4}>
<Typography variant="subtitle1">Prioritize:</Typography>
</Grid>
<Grid item xs={12} sm={8}>
<FormControl>
<RadioGroup
row
aria-label="color"
value={formik.values.priority}
onChange={formik.handleChange}
name="priority"
id="priority"
>
<FormControlLabel value="low" control={<Radio color="primary" sx={{ color: 'primary.main' }} />} label="Low" />
<FormControlLabel
value="medium"
control={<Radio color="warning" sx={{ color: 'warning.main' }} />}
label="Medium"
/>
<FormControlLabel value="high" control={<Radio color="error" sx={{ color: 'error.main' }} />} label="High" />
</RadioGroup>
</FormControl>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<Grid container alignItems="center" spacing={2}>
<Grid item xs={12} sm={4}>
<Typography variant="subtitle1">State:</Typography>
</Grid>
<Grid item xs={12} sm={8}>
<FormControl fullWidth sx={{ m: 1 }}>
<InputLabel >State of question</InputLabel>
<Select
id="state"
name="state"
displayEmpty
value={formik.values.state}
onChange={formik.handleChange}
// label='choose question state'
inputProps={{ 'aria-label': 'choose question state' }}
>
{states.map((val, index) => (
<MenuItem key={index} value={val.title}>
{val.title}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<AnimateButton>
<Button fullWidth variant="contained" type="submit">
Save
</Button>
</AnimateButton>
</Grid>
</Grid>
</LocalizationProvider>
</form>
</Box>
)}
</Drawer>
);
};
export default EditQs;
First issue is setAllUsers(readAllUsers()). You are calling setAllUsers passing a function readAllUsers as argument but inside this function you are calling setAllUsers again
.onSnapshot(function (val) {
let user = []
val.forEach(function(doc) {
user.push(doc.data().name);
// setAllUsers again
setAllUsers(user)
})})
Every time you change the state, your component is getting rerendered.
It would be better to write different useEffect for each state setup. Each useEffect will have different dependentcies. Setting correct depencencies needs analysing the code. Otherwise you might not get correct state or your component might keep rerendering
I hope your day is going well. I am a new user of material UI and I am working on building my first profile page (image below).
As I am getting closer to building this page, I am struggling to create a grid system that allows the about section to be directly under the three panels (see image below).
How do I remove the padding between the about section and three pannels (code below)?
return (
<>
<Helmet>
<title>Dashboard: Project Details | Material Kit Pro</title>
</Helmet>
<Box
sx={{
backgroundColor: 'background.default',
minHeight: '100%',
py: 8
}}
>
<Container >
<AppBar></AppBar>
<Grid container spacing={1}>
<Grid item xs={12} md={3}>
<Box
style={{ height: '100%', width: '100%'}}
>
<WritersSidePanel />
</Box>
</Grid>
<Grid item xs={12} md={9}>
<WritersPageTopPanel />
</Grid>
<Box style={{ marginDown: '90%'}}>
<Grid item xs={12} container
direction="column"
alignItems="flex-end"
justify="flex-end">
<Box
style={{ width: '75%', height: '100%'}}
>
<AboutSection description={description} />
</Box>
</Grid>
<Grid item xs={12} container
direction="column"
alignItems="flex-end"
justify="flex-end">
<Box
style={{ width: '75%'}}
>
<SampleStory description={description} />
</Box>
</Grid>
</Box>
</Grid>
</Container>
</Box>
</>
);
};
i am trying to render the elements of the array inside a custom card component inside a grid. but when the page opens it freezes and the console displays "Uncaught TypeError: Cannot read property 'muiName' of undefined"
the custom component
LookupMedication = (medicationName) => {
return (
<Grid xs={3} item>
<Card
style={{
width: "18em",
marginBottom: "2em",
}}
>
<CardActionArea>
<CardMedia
style={{
height: "8em",
}}
image={Meds}
title={medicationName}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{medicationName}
</Typography>
<TextField
fullWidth
label="Amount Available"
variant="outline"
type="number"
></TextField>
</CardContent>
</CardActionArea>
<CardActions>
<Button
fullWidth
style={{
color: "white",
backgroundColor: "#1818",
}}
startIcon={<PostAddIcon />}
>
Add
</Button>
</CardActions>
</Card>
</Grid>
);
};
the map function
<Grid container>
{this.medications.map((medication) =>
this.LookupMedication(medication)
)}
</Grid>
Any help is appreciated
You need to add muiName to your component
Underneath LookupMedication just add the code.
LookupMedication.muiName = 'Grid';
For more detail about muiName check out this answer
I have a very simple problem in my react app. I need to turn on the switch value if it is true otherwise false. I already initialize the value as true but the switch is still off.
Pls check this code-sandbox link
CLICK THIS
<Grid item xs="{12}" md="{6}">
<FormControlLabel
name="buy"
variant="outlined"
value="{values.buy}"
onChange="{handleChange}"
onBlur="{handleBlur}"
control="{<Switch"
color="primary"
/>} label="Triage?" labelPlacement="end" style={{ display: "flex",
justifyContent: "flex-end" }} />
</Grid>
You have to use checked property
...
<Switch checked={values.buy} color="primary" />
UPDATE
To be precise: add checked in the place where you pass the Switch control. All other code should not be touched
... your code
control={<Switch checked={values.buy} color="primary" />}
... your code
The on/off state of the switch is controlled by property 'checked'. You can set it in both FormControlLabel and Switch components.
Here's the code for setting it in the FormControlLabel:
<Grid item xs={12} md={6}>
<FormControlLabel
name="buy"
variant="outlined"
value={values.buy}
checked={values.buy}
onChange={handleChange}
onBlur={handleBlur}
control={<Switch color="primary" />}
label="Triage?"
labelPlacement="end"
style={{ display: "flex", justifyContent: "flex-end" }}
/>
</Grid>
Here's the second option, to set it in Switch:
<Grid item xs={12} md={6}>
<FormControlLabel
name="buy"
variant="outlined"
value={values.buy}
onChange={handleChange}
onBlur={handleBlur}
control={<Switch color="primary" checked={values.buy} />}
label="Triage?"
labelPlacement="end"
style={{ display: "flex", justifyContent: "flex-end" }}
/>
</Grid>
Both seems to work fine.