Map a React component with different keys - reactjs

I want to load components but it shows a problem that the components with the same key but I maped on selectedGroups and gave gr.id as a key it worked before the first version is
sharingTabs = selectedGroups.map(gr => (
<ExpansionPanel>
<ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
<Typography className={classes.heading}>{gr.name}</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Grid container spacing={16}>
<Grid item xs>
<SharingSpacesTabs />
</Grid>
</Grid>
</ExpansionPanelDetails>
</ExpansionPanel>
));
but then I wanted to send the index in a props that's why I added another map inside the map that's what caused the problem of call back function and I aded return
sharingTabs = selectedGroups.map(function(gr) {
const indexs = groups.map((group, index) => {
if ((group.sharingspace.element = gr.id)) {
return index;
}
});
return (
<ExpansionPanel key={gr.id}>
<ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
<Typography className={classes.heading}>{gr.name}</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Grid container spacing={16}>
<Grid item xs>
<SharingSpacesTabs id={gr.id} index={indexs[0]} />
</Grid>
</Grid>
</ExpansionPanelDetails>
</ExpansionPanel>
);
});
could you please help me find a solution I need it and thank you

I think you have problem in your condition, Change you function condition to properly check the equality with == or ===.
Also I am not sure what you want to do if the condition will not satisfied, map will return null for every element which does not satisfy the condition.
const indexs = groups.map((group, index) => {
if ((group.sharingspace.element == gr.id)) {
return index;
}
});

the best way to do it is to pass a second index as a second parameter in map and make the key={index}
sharingTabs = selectedGroups.map((gr, index) => {
const indexes = groups.map((group, index) => {
if ((group.sharingspace.element = gr.id)) {
return index;
}
});
return (
<ExpansionPanel key={index}>
<ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
<Typography className={classes.heading}>{gr.name}</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Grid container spacing={16}>
<Grid item xs>
<SharingSpacesTabs id={gr.id} index={indexes[0]} />
</Grid>
</Grid>
</ExpansionPanelDetails>
</ExpansionPanel>
);
});

Related

Warning: Received `true` for a non-boolean attribute `item`

This error shows in my dev tools when I load my app. I'm not sure how to go about changing it to fix the problem. I suspect it is a reason why when I deploy it to heroku it looks different that when I view it locally so I'm hoping if I fix this it will fix my problem with heroku as well.
Here is my code:
return (
<Container className="container" maxWidth="xl">
<CssBaseline />
{/* <Box sx={{ marginTop: 10, padding: 7, bgcolor: "#eeeeee", borderRadius: "0.3rem" }}> */}
<Grid className="homeContainer" container spacing={1}>
<Grid className="topGrid">
<Grid className="imageContainer" item xs={4} sx={{ }}>
<img className="cctLogoLarge" src={cctlogo1} alt="outline of horse with parliament buildings in background"></img>
</Grid>
<Grid className="introContainer" item xs={12}>
<p>Welcome to Cap City Trotters! The CCT was created in 2019 by KMAC, Lynch, Bruster, and Damarts. Our Routes include several loops in both Ottawa and Gatineau.
We are always looking for new members so if you want to join you can take a look at some of our main routes and signup if you like what you see!</p>
{/* Test Connect to Strava */}
</Grid>
</Grid>
<Grid >
<Grid className="postList-grid">
{/* {loggedIn && (
<div className="col-12 mb-3">
<PostForm />
</div>
)} */}
<Grid item xs={6} sx={{ bgcolor: ""}} className="recentPosts">
{loading ? (
<div>Loading...</div>
) : (
<PostList posts={posts}/>
)}
</Grid>
{loggedIn && userData ? (
<Grid>
{/* <FriendList
username={userData.me.username}
friendCount={userData.me.friendCount}
friends={userData.me.friends}
/> */}
</Grid>
) : null}
</Grid>
</Grid>
{/* </Box> */}
</Grid>
</Container>
)
I've looked at similar questions and answers but can't figure out how to solve this problem specifically.
Thanks in advance!
Whenever you add a prop without a value to React component, it evaluates to true:
<MyComponent boo />
Here, MyComponent receives a boo = true property. That's what you have in your code with item, while it shouldn't be a boolean value. Just pass some value to item:
<Grid item={somethingElse}>

Adding Dynamic States to React JS project

I am creating an emojipedia app where it is expected to open a Modal, which contains the description of the emoji, when an emoji is pressed. As far as I know, to do so, I need to map the description(contained in emojipedia.js file) of the emoji to the EmojiContainer component in Components folder.
Here comes my problem where when I press a emoji, it is getting hanged. Why is this happening and how to fix this???
THANKS IN ADVANCE.
You are using a single state on EmojiContainer to control all modals in your emoji list. As a consequence, when you try and open a modal, all modals open. A better option would be to encapsulate all logic relative to a single modal in a separate, reusable component:
export default function Emoji({ item }) {
const [open, setOpen] = useState(false);
return (
<Grid item lg={2} md={3} xs={6}>
<ImageButton onClick={() => setOpen(true)}>
<CardMedia
sx={{
"&:hover": {
transform: "scale(1.3)"
}
}}
component="img"
height="100"
image={item.link}
alt="emoji"
/>
</ImageButton>
<Modal
open={open}
onClose={() => setOpen(false)}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Typography sx={style} variant="p">
{item.desc}
</Typography>
</Modal>
</Grid>
);
}
As you see this component has its own state and controls its own modal. In your EmojiContainer you can use it like this:
export default function EmojiContainer() {
return (
<Grid>
{emojipedia.map((item, index) => (
<Grid key={index} container>
<Emoji item={item} />
</Grid>
))}
</Grid>
);
}
From what I see you'll also need to adjust the modal styling. Here's the updated codesandbox

Grid system breakpoint override?

I need some help. I use material-ui Grid system, and my full page is responsive like a charm, but i need at grid components overflowX with fixed header, so only the Grid container should be a horizontal scrollbar, but i tried a lot of things but nothing works.
I have this gird system. So i would like horizontal scrolling when im generated more grid item.
This is my code-snippet for this part.
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="droppable" direction={windowInnerWidth > 1280 ? 'horizontal' : 'vertical'} type="droppableItem">
{(provided, snapshot) => (
<div>
{windowInnerWidth > 1280 ? (
<Grid container spacing={6} ref={provided.innerRef} {...provided.droppableProps} >
{mergedData &&
mergedData.map((section, index) => (
<Grid item xs={12} xl="auto" lg="auto" key={section.uid} >
<Draggable
key={section.id}
draggableId={section.id}
index={index}
// isDragDisabled={false}
>
{(provided, snapshot) => (
<Card ref={provided.innerRef} {...provided.draggableProps} style={provided.draggableProps.style}>
<CardContent key={section.uid} index={props.index}>
<MyWorkoutSectionListItem
type={section.id} // type
key={section.id}
section={section}
provided={provided}
index={index}
workouts={section.workouts.filter((workout) => {
return workout.title.toLowerCase().includes(props.search.toLowerCase());
})} // subItems
workoutSections={props.workoutSections}
sectionName={props.sectionName}
defaultSectionId={defaultSectionId}
deleteSection={props.deleteSection}
handleWorkoutChange={props.handleWorkoutChange}
handleSectionChange={props.handleSectionChange}
changeMergeData={props.changeMergeData}
/>
{provided.placeholder}
</CardContent>
</Card>
)}
</Draggable>
</Grid>
))}
{provided.placeholder}
It would be great if somebody has idea for this problem.
You need to Use wrap={"nowrap"} prop on container Grid component and also need to provide the overflowX="auto".
Something like this
....
<Grid container spacing={2} wrap={"nowrap"} style={{ overflowX: "auto" }}>
<Grid item>Hello</Grid>
<Grid item>Hello</Grid>
</Grid>
...
I have created this Code sandbox project with the exact implementations

React Parsing failed ,Unexpected token

i am trying to create a Dynamic Material UI Flex box that generate a new row based on backend . my idea is to close the current outer Box and create a new one based on a flag
so i write the following code
<Box p="1em">
<Box display="flex">
{tabs.map((t, index) => {
return (
<>
<Box flex={resourcesTabs[index][0] == null ? 1 : resourcesTabs[index][0]['width_class']} ml="1em">
<Typography variant="h6" gutterBottom>{t}</Typography>
{resourcesFields[index] && resourcesFields[index].map((f, index) =>
generateInputField(f, index)
)}
</Box>
{resourcesTabs[index][0]['new_line_after'] && </Box><Box display="flex">}
</>
);
})}
</Box>
</Box>
But i recive the following Error
Parsing error: Unexpected token
as it complain about close open tags dynamic for this line
{resourcesTabs[index][0]['new_line_after'] && (</Box><Box display="flex">}
any idea how to solve this ?
There is a sneaky parenthesis:
{resourcesTabs[index][0]['new_line_after'] && => ( <= </Box><Box display="flex">}
i fixed it by replace box with grid as the following code
<div style={{ padding: 10 }}>
<Grid container spacing={3}>
{tabs.map((t, index) => {
return (
<>
<Grid item xs={resourcesTabs[index][0] == null ? 6 : resourcesTabs[index][0]['width_class']} >
<Typography variant="h6" gutterBottom>{t}</Typography>
{resourcesFields[index] && resourcesFields[index].map((f, index) =>
generateInputField(f, index)
)}
</Grid>
</>
);
}
)}
</Grid>
</div>

Conditional operator returning undefined in render method

I've added some piece of code in render method of react using conditional (ternary) operator. The thing is the condition is rendered true also the control goes into the block. But when I print the value the variable is undefined
I tried inserting an alert inside the block to check if the control traverses the block and it worked.
const comments =
details.comments_count >= 1
? Object.keys(details.comments_list).forEach(keys => {
return (
<ListItem
alignItems="flex-start"
key={details.comments_list[keys].aid}
>
<ListItemAvatar>
<Avatar>{details.comments_list[keys].aname.charAt(0)}</Avatar>
</ListItemAvatar>
<Card style={useStyles.card}>
<CardContent>
<ListItemText
primary={details.comments_list[keys].aname}
secondary={details.comments_list[keys].content}
/>
</CardContent>
</Card>
</ListItem>
);
})
: null;
console.log(comments);
//=>undefined
I don't actually know why this this is happening, given the result of conditional expression is true. Any help is appreciated. Thanks.
forEach won't return anything but undefined. You need to use map.
const comments =
details.comments_count >= 1
? Object.keys(details.comments_list).map(keys => {
return (
<ListItem
alignItems="flex-start"
key={details.comments_list[keys].aid}
>
<ListItemAvatar>
<Avatar>{details.comments_list[keys].aname.charAt(0)}</Avatar>
</ListItemAvatar>
<Card style={useStyles.card}>
<CardContent>
<ListItemText
primary={details.comments_list[keys].aname}
secondary={details.comments_list[keys].content}
/>
</CardContent>
</Card>
</ListItem>
);
})
: null;
console.log(comments);

Resources