Warning: encountered two children with the same key, is appearing as an error in my REACT app - javascript

I'm in the process of building out a simple react act that display REST data from my localhost URL.
I keep getting this error and I'm not sure why, at first I thought it was the data within the API itself but I think that's not the case for this?
I am not getting any npm start errors, the error appears when I inspect a page with browser tools.
Here is the full error:
index.js:1 Warning: Encountered two children with the same key, `1`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
at div
at Grid (http://localhost:4000/static/js/0.chunk.js:1556:35)
at WithStyles(ForwardRef(Grid)) (http://localhost:4000/static/js/0.chunk.js:6385:31)
at main
at Container (http://localhost:4000/static/js/0.chunk.js:1101:23)
at WithStyles(ForwardRef(Container)) (http://localhost:4000/static/js/0.chunk.js:6385:31)
at UserBuckets (http://localhost:4000/static/js/main.chunk.js:363:5)
at LoadingComponent (http://localhost:4000/static/js/main.chunk.js:999:5)
at div
at App (http://localhost:4000/static/js/main.chunk.js:173:89)
at Route (http://localhost:4000/static/js/0.chunk.js:48473:29)
at Switch (http://localhost:4000/static/js/0.chunk.js:48675:29)
at Router (http://localhost:4000/static/js/0.chunk.js:48108:30)
at BrowserRouter (http://localhost:4000/static/js/0.chunk.js:47728:35)
Could someone point out what is causing this error in my code? I haven't been able to solve it myself.
Here is my required code:
App.js
import React, { useEffect, useState } from 'react';
import './App.css';
import UserBuckets from './components/BucketLists';
import LoadingComponent from './components/Loading';
function App() {
const ListLoading = LoadingComponent(UserBuckets);
const [appState, setAppState] = useState({
loading: false,
buckets: null,
});
useEffect(() => {
setAppState({ loading: true });
const apiUrl = `http://127.0.0.1:8000/api/`;
fetch(apiUrl)
.then((data) => data.json())
.then((buckets) => {
setAppState({ loading: false, buckets: buckets });
});
}, [setAppState]);
return (
<div className="App">
<h1>Latest Buckets</h1>
<ListLoading isLoading={appState.loading} buckets={appState.buckets} />
</div>
);
}
export default App;
bucketList.js
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Card from '#material-ui/core/Card';
import CardContent from '#material-ui/core/CardContent';
import CardMedia from '#material-ui/core/CardMedia';
import Grid from '#material-ui/core/Grid';
import Typography from '#material-ui/core/Typography';
import Container from '#material-ui/core/Container';
const useStyles = makeStyles((theme) => ({
cardMedia: {
paddingTop: '56.25%', // 16:9
},
link: {
margin: theme.spacing(1, 1.5),
},
cardHeader: {
backgroundColor:
theme.palette.type === 'light'
? theme.palette.grey[200]
: theme.palette.grey[700],
},
bucketTitle: {
fontSize: '16px',
textAlign: 'left',
},
bucketText: {
display: 'flex',
justifyContent: 'left',
alignItems: 'baseline',
fontSize: '12px',
textAlign: 'left',
marginBottom: theme.spacing(2),
},
}));
const UserBuckets = (props) => {
const { buckets } = props;
const classes = useStyles();
if (!buckets || buckets.length === 0) return <p>Can not find any buckets, sorry</p>;
return (
<React.Fragment>
<Container maxWidth="md" component="main">
<Grid container spacing={5} alignItems="flex-end">
{buckets.map((buckets) => {
return (
// Enterprise card is full width at sm breakpoint
<Grid item key={buckets.owner} xs={12} md={4}>
<Card className={classes.card}>
<CardMedia
className={classes.cardMedia}
image="https://source.unsplash.com/random"
title="Image title"
/>
<CardContent className={classes.cardContent}>
<Typography
gutterBottom
variant="h6"
component="h2"
className={classes.bucketTitle}
>
{buckets.name.substr(0, 50)}...
</Typography>
<div className={classes.bucketText}>
<Typography
component="p"
color="textPrimary"
></Typography>
<Typography variant="p" color="textSecondary">
{buckets.stock_list}...
</Typography>
</div>
</CardContent>
</Card>
</Grid>
);
})}
</Grid>
</Container>
</React.Fragment>
);
};
export default UserBuckets;
Loading.js
import React from 'react';
function LoadingComponent(Component) {
return function LoadingComponent({ isLoading, ...props }) {
if (!isLoading) return <Component {...props} />;
return (
<p style={{ fontSize: '25px' }}>
We are waiting for the data to load!...
</p>
);
};
}
export default LoadingComponent;
Thank in advance...

The error came from this culprit and my mistake not seeing the important of the letter key in item key. This is how I solved my error:
original code
<Grid item key={buckets.owner} xs={12} md={4}>
fixed code
<Grid item key={buckets.id} xs={12} md={4}>

Related

How to use map in react component using nextjs app?

I have data returned from the backend as an array that i want to populate on react component.
home.js
import Head from "next/head";
import Header from "../src/components/Header";
import * as React from 'react';
import { styled } from '#mui/material/styles';
import Box from '#mui/material/Box';
import Paper from '#mui/material/Paper';
import Grid from '#mui/material/Grid';
import TextField from '#mui/material/TextField';
import SendIcon from '#mui/icons-material/Send';
import Stack from '#mui/material/Stack';
import Button from '#mui/material/Button';
import getDupImages from "../src/services/getDupImages";
import { useState, useEffect } from 'react'
const Item = styled(Paper)(({ theme }) => ({
backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff',
...theme.typography.body2,
padding: theme.spacing(1),
textAlign: 'center',
color: theme.palette.text.secondary,
}));
export default function Home({data}) {
let _data;
const fetchData = async () => {
_data = await getDupImages();
console.log("DATA>>>", _data);
return _data;
};
const submit = (event) => {
event.preventDefault();
fetchData();
}
return (
<>
<Head>
<title>De-Dup</title>
<link rel="icon" type="image/ico" href="/img/goals.ico" />
</Head>
<Header />
<section>
<Box sx={{ flexGrow: 1 }}>
<Grid container spacing={2}>
<Grid item xs={5}>
<Box
component="form"
sx={{
'& > :not(style)': { m: 1, width: '75ch' },
}}
noValidate
autoComplete="off"
>
<TextField id="outlined-basic" label="location path" variant="outlined" />
<Stack direction="row" spacing={2}>
<Button variant="contained" onClick={submit} endIcon={<SendIcon />}>
Submit
</Button>
</Stack>
</Box>
</Grid>
<Grid item xs={7}>
{data.map((d) => {
return (
<div>
{d.title}
</div>
);
})}
</Grid>
</Grid>
</Box>
</section>
</>
);
}
Error
1 of 1 unhandled error
Server Error
TypeError: Cannot read property 'map' of undefined
This error happened while generating the page. Any console logs will be displayed in the terminal window.
Put the data in the component state and check if there actually is data before displaying it.
const [data, setData] = useState();
const fetchData = async () => {
setData(await getDupImages());
}
Then in your JSX:
{!!data && data.map(d => <div>{d.title}</div>}
You are trying to render the data before it is available. Use this instead
{data && data.map((d) => {
return (
<div>
{d.title}
</div>
);
})}
Either initialise the data state as an array or use the Optional chaining (?.) operator before the map function:
data?.map((d) => {
return <div>{d.title}</div>;
})
Hope this helps.

TypeError: Cannot read properties of undefined (reading 'map') react

I'm trying to get a Tv show to display on multiple cards. I'm just using one Tv show before I start adding any more. So it should basically display one tv show on all the cards.
The error is coming from the tvList.js.
tvList.js
import React from "react";
import Tv from "../tvCard/";
import Grid from "#material-ui/core/Grid";
const TvList = (props) => {
let tvCards = props.tvshows.map((m) => (
<Grid key={m.id} item xs={12} sm={6} md={4} lg={3} xl={2}>
<Tv key={m.id} tv={m} />
</Grid>
));
return tvCards;
};
export default TvList;
The Tv card seems to be fine and is working in my storybook.
tvCard.js
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Card from "#material-ui/core/Card";
import CardActions from "#material-ui/core/CardActions";
import CardContent from "#material-ui/core/CardContent";
import CardMedia from "#material-ui/core/CardMedia";
import CardHeader from "#material-ui/core/CardHeader";
import Button from "#material-ui/core/Button";
import Typography from "#material-ui/core/Typography";
import FavoriteIcon from "#material-ui/icons/Favorite";
import CalendarIcon from "#material-ui/icons/CalendarTodayTwoTone";
import StarRateIcon from "#material-ui/icons/StarRate";
import IconButton from "#material-ui/core/IconButton";
import Grid from "#material-ui/core/Grid";
import img from '../../images/tv-poster-placeholder.png'
const useStyles = makeStyles({
card: { maxWidth: 345 },
media: { height: 500 },
avatar: {
backgroundColor: "rgb(255, 0, 0)",
},
});
export default function TvCard(props) {
const classes = useStyles();
const tv = props.tv;
return (
<Card className={classes.card}>
<CardHeader className={classes.header} title={tv.name} />
<CardMedia
className={classes.media}
image={
tv.poster_path
? `https://image.tmdb.org/t/p/w500/${tv.poster_path}`
: img
}
/>
<CardContent>
<Grid container>
<Grid item xs={6}>
<Typography variant="h6" component="p">
<CalendarIcon fontSize="small" />
{tv.first_air_date}
</Typography>
</Grid>
<Grid item xs={6}>
<Typography variant="h6" component="p">
<StarRateIcon fontSize="small" />
{" "} {tv.vote_average}{" "}
</Typography>
</Grid>
</Grid>
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="add to favorites" onClick={null}>
<FavoriteIcon color="primary" fontSize="large" />
</IconButton>
<Button variant="outlined" size="medium" color="primary">
More Info ...
</Button>
</CardActions>
</Card>
);
}
tvPage.js
import React from "react";
import Header from "../components/headerTvList";
import FilterCard from "../components/filterTvCard";
import Grid from "#material-ui/core/Grid";
import { makeStyles } from "#material-ui/core/styles";
import TvList from "../components/tvList";
const useStyles = makeStyles({
root: {
padding: "20px",
},
});
const TvListPage = (props) => {
const classes = useStyles();
const tvshows = props.tvshows;
return (
<Grid container className={classes.root}>
<Grid item xs={12}>
<Header title={"Discover Tv Shows"} />
</Grid>
<Grid item container spacing={5}>
<Grid key="find" item xs={12} sm={6} md={4} lg={3} xl={2}>
<FilterCard />
</Grid>
<TvList tvshows={tvshows}></TvList>
</Grid>
</Grid>
);
};
export default TvListPage;
src/index.js
import React from "react";
import ReactDOM from "react-dom";
import TvPage from "./pages/tvPage";
const sample = {
"backdrop_path": "/wAEWZm2pSopAbqE5dQWE0ET8aR5.jpg",
"first_air_date": "2021-01-08",
"genre_ids": [
10759,
10765,
99
],
"id": 114695,
"name": "Marvel Studios: Legends",
"origin_country": [
"US"
],
"original_language": "en",
"original_name": "Marvel Studios: Legends",
"overview": "Revisit the epic heroes, villains and moments from across the MCU in preparation for the stories still to come. Each dynamic segment feeds directly into the upcoming series — setting the stage for future events. This series weaves together the many threads that constitute the unparalleled Marvel Cinematic Universe.",
"popularity": 140.788,
"poster_path": "/EpDuYIK81YtCUT3gH2JDpyj8Qk.jpg",
"vote_average": 7.6,
"vote_count": 515
}
const tvshows = [sample, sample, sample, sample, sample, sample, sample];
const App = () => {
return (
<TvPage tvshows={tvshows} />
);
};
ReactDOM.render(<App />, document.getElementById("root"));
It could be an with the tvPage component.
const tvshows = props.tvshows;
Here the value of tvshows might be empty initially. I'd suggest i your TvList component do an null check.
const TvList = (props) => {
let tvCards = props.tvshows?.map((m) => (
<Grid key={m.id} item xs={12} sm={6} md={4} lg={3} xl={2}>
<Tv key={m.id} tv={m} />
</Grid>
));
return tvCards;
};
The ? is an [optional chaining] operator(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining).
The error is that for some reason, props.tvshows is undefined within TvList, even though it should be passed down from App to TvPage to TvList. At some point down the line, tvshows is lost.
I would suggest logging all instances of tvshows, starting from when it is first defined in App, then logging in TvPage, then TvList, to see where exactly the problem is coming from. Once you've found it, do some debugging to make the problem stop.

react-map-gl and using useContext and/or useState to change viewport from another component

I seem to be not understand anything lately and having a tough time grasping useContext and/or useState with React/Nextjs and react-map-gl.
Basically, I have two components. A searchbox utilizing Formik & a Map from react-map-gl. What I want to do is be able to have one of the variables from Formik be able to change the viewport on react-map-gl so it redirects the viewport of the map to the new coordinates. I tried researching and reading about what I can do to make this work but I just can't grasp it. I believe it has to be something simple and I'm just too new to understand. Every time I think I have it I get a error saying I can't actually do that.
For reference here's my current code using useState. Whenever I try to use it and hit the submit button I get " 1 of 1 unhandled error
Unhandled Runtime Error
TypeError: setViewport is not a function
"
which doesn't seem to make any sense :( . Other times when I can get it to work, I have to click the submit button twice to get the form to register the new setViewport. What am I doing wrong? Thank you for your help!
index.js
import { Grid } from '#material-ui/core';
import { useState } from 'react';
import SearchBox from '../components/searchbox';
import {
getAllCampgrounds,
getAllCities,
getCampgroundsByCity,
} from '../lib/api';
import Map from '../components/map';
export default function CampList({
graphCampgrounds,
cities,
campgroundsbycity,
}) {
const [viewport, setViewport] = useState({
height: '100vh',
latitude: 44.0456,
longitude: -71.6706,
width: '100vw',
zoom: 8,
});
return (
<Grid container spacing={3}>
<Grid item xs={12} sm={5} md={3} lg={2}>
<SearchBox
graphCampgrounds={graphCampgrounds}
cities={cities}
campgroundsbycity={campgroundsbycity}
setViewport={() => setViewport}
/>
</Grid>
<Grid item xs={12} sm={7} md={9} lg={10}>
<Map
campgrounds={graphCampgrounds}
viewport={viewport}
setViewport={() => setViewport}
/>
<pre style={{ fontSize: '2.5rem' }}>{}</pre>
</Grid>
</Grid>
);
}
I omitted my getServerSideProps area. Here is my Searchbox.js:
import Link from 'next/link';
import { Form, Formik, Field, useFormik } from 'formik';
import {
Paper,
Grid,
FormControl,
InputLabel,
Select,
MenuItem,
Button,
} from '#material-ui/core';
import { makeStyles } from '#material-ui/core/styles';
import { useRouter } from 'next/router';
const useStyles = makeStyles(theme => ({
paper: {
margin: 'auto',
maxWidth: 500,
padding: theme.spacing(3),
},
}));
export default function SearchBox({
graphCampgrounds,
cities,
campgroundsbycity,
viewport,
setViewport,
}) {
const router = useRouter();
const { query } = router;
const handleSubmit = async values => {
setViewport({
...viewport,
latitude: campgroundsbycity
? parseFloat(campgroundsbycity.nodes[0].acfDetails.latitude.toFixed(4))
: 44.43,
longitude: campgroundsbycity
? Math.abs(
parseFloat(campgroundsbycity.nodes[0].acfDetails.longitude.toFixed(4))
) * -1
: -72.352,
zoom: 11,
});
router.push(
{
pathname: '/camps',
query: { ...values, page: 1 },
},
undefined,
{ shallow: true }
);
};
const classes = useStyles();
const smValue = singleColumn ? 12 : 6;
const initialValues = {
city: query.city || 'all'
};
return (
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
{({ values, submitForm }) => (
<Form>
<Paper className={classes.paper} elevation={5}>
<Grid container spacing={3}>
<Grid item xs={12} sm={smValue}>
<FormControl fullWidth variant="outlined">
<InputLabel id="search-cities">City</InputLabel>
<Field
name="city"
as={Select}
labelId="search-cities"
label="Cities"
>
<MenuItem value="all">
<em>All</em>
</MenuItem>
{cities.nodes.map(town => {
return (
<MenuItem
key={town.acfDetails.city}
value={town.acfDetails.city}
>
{town.acfDetails.city}
</MenuItem>
);
})}
</Field>
</FormControl>
</Grid>
<Grid item xs={12}>
<Button
color="primary"
variant="outlined"
type="button"
fullWidth
onClick={submitForm}
>
Search Campgrounds
</Button>
</Grid>
</Grid>
</Paper>
</Form>
)}
</Formik>
);
}
And here's my map component:
import { useContext, useMemo } from 'react';
import ReactMapGL, { Marker, MapContext } from 'react-map-gl';
import { ViewportContext } from '../lib/state';
export default function Map({ campgrounds, viewport, setViewport }) {
const markers = campgrounds.map(({ node }) => {
console.log(node.acfDetails);
return (
<Marker
key={node.title}
longitude={
Math.abs(parseFloat(node.acfDetails.longitude.toFixed(4))) * -1
}
latitude={parseFloat(node.acfDetails.latitude.toFixed(4))}
>
<img src="pin.png" alt={node.title} />
</Marker>
);
});
return (
<ReactMapGL
mapboxApiAccessToken={process.env.NEXT_PUBLIC_MAPBOX_KEY}
mapStyle="mapbox://styles/mapbox/outdoors-v11"
{...viewport}
onViewportChange={nextViewport => setViewport(nextViewport)}
>
{markers}
</ReactMapGL>
);
}
Agreed with #juliomalves's answer.
In you index.js, pass the function setViewport to your SearchBox and Map components by setViewport={setViewport}.
That is how React hooks should be called.

props in functional component

I am not very familiar with using props in function components and I want to basically connect two functions in one functional component, and use the data from it.
Here is my code. I want to fetch data from a database and display it in cards using the map method.
import {React, useEffect, useState} from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Card from '#material-ui/core/Card';
import CardActions from '#material-ui/core/CardActions';
import CardContent from '#material-ui/core/CardContent';
import Button from '#material-ui/core/Button';
import Typography from '#material-ui/core/Typography';
import clueData from './ClueData';
import client from '../api/client';
import { Chip, Container, Grid } from '#material-ui/core';
const RenderClues=(index)=> {
const classes= useStyles();
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await client.get('api/admin/mission')
setData(result.data.Missions);
}
fetchData();
}, []);
return (
<Card key={index} data={data} style={{ marginBottom: 10, padding: 10 }}>
<CardContent>
<div className={classes.container}>
<Typography className={classes.title} color="textSecondary" variant="ul" >
Clue : {data.cluename}
</Typography>
<Chip size="small" label={clue.isSolved? "solved" : "unsolved" } />
</div>
</CardContent>
<CardActions style={{ display: 'flex', justifyContent: 'space-between'}}>
<Button variant="contained" size="small" href="/photo-clue">View</Button>
<Typography color="textSecondary">
{data.points}
</Typography>
</CardActions>
</Card>
);
}
function Clues(props) {
return (
<Container maxWidth="md">
<Grid item xs={12} >
{props.data.map(RenderClues)}
</Grid>
</Container>
);
}
export default Clues;
const useStyles = makeStyles({
title: {
fontSize: 20,
color:"olive",
fontWeight: 'bold',
textAlign: 'left',
},
pos: {
marginBottom: 12,
},
points: {
float:"right",
},
container: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 10,
}
});
But there is something wrong in the way I am using props here because I m getting this error:
"Cannot read property 'map' of undefined."
Any help is appreciated. Thanks!
Issue is props.data being undefined at the point of time its rendered.. If asynchrounsly updated, then try this.
{props?.data?.map(RenderClues)}
Map function takes key, and items.
For Example:
props.data.map((key, items) => RenderClues)
First of all, you should run fetchData() inside Clues function. After fetching data, pass your data as props to RenderClues like below:
<Grid item xs={12} >
data.map((dataItem) => {
<RenderClues key={something uniq} data={dataItem} />
})
</Grid>
By the way, you have to change RenderClues to RenderClues = (props) => {your code} and use props inside RenderClues. And in the code above, i'm assuming you fetch data like that. You need to change that too

Map not re-rendering

I am trying to use the map function but it wont rerender my select box with the updated selected value.
The filter is on a material ui dialog that pops up when you view a file. The values will update when i close the modal and reopen it but wont update if i dont close the window. Any help would be greatly appriciated.
import React, { useEffect, useState } from 'react';
import Grid from '#material-ui/core/Grid';
import Paper from '#material-ui/core/Paper';
import InputLabel from '#material-ui/core/InputLabel';
import FormControl from '#material-ui/core/FormControl';
import Select from '#material-ui/core/Select';
import { makeStyles } from '#material-ui/core/styles';
import MenuItem from '#material-ui/core/MenuItem';
import filter from '../../../constants/filter-options';
export default function KeywordFilter(props) {
const [selectedFilter, setFilter] = useState(props.selectedFilter);
const [filterOptions, setFilterOptions] = useState(filter);
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.primary,
},
modal: {
height: '80vh',
width: '40vw',
maxWidth: '40vw'
}
}));
const classes = useStyles();
const handleChange = (event, keyword) => {
var temp = selectedFilter;
temp[keyword] = event.target.value;
console.log("TEMP: ", temp)
console.log("keywordList: ", keywordList)
props.onFilterChange(temp);
setFilter(temp)
setFilterOptions(filter)
};
const keywordList = Object.keys(filterOptions)
return (
<div key={keywordList}>
<h4 style={{textAlign:'center'}}>Filters: </h4>
<Grid container spacing={3}>
{keywordList.map((keyword) => {
return (
<Grid item xs={6}>
{console.log("selectedFilter: ", selectedFilter)}
<Paper className={classes.paper}>
{keyword}: <FormControl className={classes.formControl}>
<Select
key={keyword}
labelId="demo-simple-select-label"
id="demo-simple-select"
value={selectedFilter[keyword] ? selectedFilter[keyword] : "None"}
onChange={(e) => handleChange(e, keyword)}
>
{filterOptions[keyword].map(element => <MenuItem value={element}>{element}</MenuItem>)}
</Select>
</FormControl>
</Paper>
</Grid>
)}
)}
</Grid>
</div>
);
}
The filter file looks like the following:
const filter =
{
Schedule : ["None", "Monthly", "Quarterly", "Semi-Annually", "Annually"],
Chemical : ["None", "Copper", "Phosphorus"],
Color : ["None", "Black", "Blue"]
}
export default filter;
It turns out I was modifying the state directly and that was creating a bunch of issues. The following changes to the handleChange function and removing unnecessary code fixed the issue:
import React, { useEffect, useState } from 'react';
import Grid from '#material-ui/core/Grid';
import Paper from '#material-ui/core/Paper';
import FormControl from '#material-ui/core/FormControl';
import Select from '#material-ui/core/Select';
import { makeStyles } from '#material-ui/core/styles';
import MenuItem from '#material-ui/core/MenuItem';
import filter from '../../../constants/filter-options';
export default function KeywordFilter(props) {
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.primary,
},
modal: {
height: '80vh',
width: '40vw',
maxWidth: '40vw'
}
}));
const classes = useStyles();
const handleChange = (event, keyword) => {
//deep copy selected filters to avoid directly changing state
const target = JSON.parse(JSON.stringify(props.selectedFilter))
//set new value to add
const source = { [keyword]: event.target.value};
//merge the 2 objects (this will update target aswell)
const results = Object.assign(target, source)
//update state
props.onFilterChange(results)
};
return (
<>
<h4 style={{textAlign:'center'}}>Filters: </h4>
<Grid container spacing={3}>
{Object.keys(filter).map((keyword) => {
return (
<Grid item xs={6}>
<Paper className={classes.paper}>
{keyword}: <FormControl className={classes.formControl}>
<Select
key={keyword}
labelId="demo-simple-select-label"
id="demo-simple-select"
value={props.selectedFilter[keyword] ? props.selectedFilter[keyword] : "None"}
onChange={(e) => handleChange(e, keyword)}
>
{filter[keyword].map(element => <MenuItem value={element}>{element}</MenuItem>)}
</Select>
</FormControl>
</Paper>
</Grid>
)}
)}
</Grid>
</>
);
}

Categories