Google maps doens't load in my react app (feat, GoogleMapReact) - reactjs

I'm trying to make a react app that loads a google map.
but somehow the map doesn't show and not an error was reported in console logs....
import React from 'react'
import GoogleMapReact from 'google-map-react'
import {Paper, Typography, useMediaQuery} from '#material-ui/core'
import LocationOnOutlinedIcon from '#material-ui/icons/LocationOnOutlined'
import Rating from '#material-ui/lab'
import useStyles from './styles'
const Map = () => {
const classes = useStyles()
const isMobile = useMediaQuery('(min-width:600px)')
const coordinates = { lat:0, lng: 0}
return (
<div className={classes.mapContainer}>
<GoogleMapReact
bootstrapURLKeys={{ key: 'AIzaSyBrSAzFufdmJBVojpd7idemPVGp8HskFKY' }}
defaultCenter={coordinates}
center={coordinates}
defaultZoom={14}
margin={[50,50,50,50]}
>
</GoogleMapReact>
</div>
)
}
export default Map
ㄴ this is Map.js file
import Header from "./components/Header/Header";
import {List} from "./components/List/List";
import Map from "./components/Map/Map";
import {CssBaseline, Grid} from '#material-ui/core';
function App() {
return (
<div className="App">
<CssBaseline></CssBaseline>
<Header/>
<Grid container spacing={3} style={{ width: '100%'}}>
<Grid item xs={12} md={4}>
<List/>
</Grid>
<Grid item xs={12} md={8}>
<Map/>
</Grid>
</Grid>
</div>
);
}
export default App;
ㄴthis is App.js file
enter image description here
What's causing the error(if that is an error)?
j
How can I make the map show up in my app?

Related

React Props not populated

Trying to learn React and following this tutorial:https://youtu.be/GDa8kZLNhJ4?t=3547
There you have a App.js component that makes Travel Advisor API call that populates the data object:
import React, { useState, useEffect } from "react";
import { CssBaseline, Grid } from "#material-ui/core";
import { getPlacesData } from "./api";
import Header from "./components/Header/Header";
import List from "./components/List/List";
import Map from "./components/Map/Map";
import { PlaceSharp } from "#material-ui/icons";
const App = () => {
const [places, setPlaces] = useState([]);
const [coordinates, setCoordinates] = useState({});
const [bounds, setBounds] = useState(null);
useEffect(() => {
getPlacesData().then((data) => {
console.log(data) // data is there
setPlaces(data);
});
}, []);
return (
<>
<CssBaseline />
<Header />
<Grid container spacing={3} style={{ width: "100%" }}>
<Grid item xs={12} md={4}>
<List />
</Grid>
<Grid item xs={12} md={8}>
<Map
setCoordinates={setCoordinates}
setBounds={setBounds}
coordinates={coordinates}
/>
</Grid>
</Grid>
</>
);
};
export default App;
The following props are passed to Map component:
<Map
setCoordinates={setCoordinates}
setBounds={setBounds}
coordinates={coordinates}
/>
In Map component it gets passed to GoogleMapReact component:
import React from 'react'
import GoogleMapReact from 'google-map-react'
import {Paper, Typography, useMediaQuery} from '#material-ui/core'
import LocationOnOutlinedIcon from '#material-ui/icons/LocationOnOutlined'
import Rating from "#material-ui/lab"
import useStyles from './styles'
const Map = ({setCoordinates, setBounds, coordinates}) => {
const classes = useStyles()
const isMobile = useMediaQuery('(min-width: 600px)')
//console.log(coordinates)
//const coordinates= {lat: 0, lng: 0}
return (
<div className={classes.mapContainer}>
<GoogleMapReact
bootstrapURLKeys={{ key: 'xxxxxxxxxxxxxxxxxxxx'}}
defaultCenter ={coordinates}
center = {coordinates}
defaultZoom = {14}
margin = {[50, 50, 50, 50]}
options = {''}
onChange = {(e) => {
console.log(e) // this is empty but it should have data
setCoordinates({lat: e.center.lat, lng: e.center.lng});
}}
onChildClick = {''}
>
</GoogleMapReact>
</div>
)
}
export default Map
For some reason coordinates prop is not populated in onChange as seen in the video.
I double check the code and cannot find what is stopping it from getting the data.
The API call returns a bunch of restaurants like this:
So it is fetching the data. Only props {coordinates} not getting filled.
Can you see where can be the issue?
There are two pieces of state that handle some state. Those are places and coordinates. Once the App component is loaded, it tries to fetch places and update its state, triggering a re rendering. So far, so good.
The Map Component receives as prop the value of coordinates. coordinates never changes in the flow of the snippet that you posted. Maybe you want to fetch some coordinates from another endpoint? Or maybe from the places data, map through it and set a new state?. Same applies for bounds.
What it looks like it is missing is a call to setCoordinates and setBounds with the new values.

Why material-ui components don't display in my App?

So I'm following a react tutorial and in that project material-ui is being used, it's e-commerce, so I have Products.jsx and Product.jsx files.
Product.jsx file:
import React from 'react';
import { Card, CardMedia, CardContent, CardActions, Typography, IconButton} from '#material-ui/core';
import { AddShoppingCart } from '#material-ui/icons';
import MuiThemeProvider from '#material-ui/core/styles/MuiThemeProvider';
const Product = ( {product} ) => {
return (
<MuiThemeProvider>
<Card className="rootie">
<CardMedia className="media" image='' title={product.name} />
<CardContent>
<div className="cardContent">
<Typography variant="h5" gutterBottom>
{product.name}
</Typography>
<Typography variant="h5" gutterBottom>
{product.price}
</Typography>
</div>
<Typography variant="h2" color="textSecondary">{product.description}</Typography>
</CardContent>
<CardActions disableSpacing className="cardActions">
<IconButton aria-label="Add to cart">
<AddShoppingCart/>
</IconButton>
</CardActions>
</Card>
</MuiThemeProvider>
);
}
export default Product;
Products.jsx:
import React from 'react';
import { Grid } from '#material-ui/core';
import Product from '../Product/Product';
import MuiThemeProvider from '#material-ui/core/styles/MuiThemeProvider';
const products = [
{ id: 1, name: 'JBL', description: 'JBL', price: '$100'},
{ id: 2, name: 'AirPods', description: 'AirPods', price: '$100'},
];
const Products = () => {
return (
<MuiThemeProvider>
<Grid container justifyContent="center" spacing={4}>
{products.map((product) =>{
<Grid item key={product.id} xs={12} sm={6} md={4} lg={3}>
<Product product={product}/>
</Grid>
})}
</Grid>
</MuiThemeProvider>
);
}
export default Products;
And my App.js looks like this:
import React from 'react';
import Header from './components/Header/Header';
import Products from './components/Products/Products';
import './App.scss';
const App = () => {
return (
<div>
<Products/>
</div>
)
}
export default App;
So as you see, everything looks okay, but for some reason React doesn't render the components, so the page looks empty. I've searched on the internet and found about 'MuiThemeProvider', but adding it didn't really help either.
You need to create a theme and pass it as prop to ThemeProvider which in turn wraps the entire App during ReactDOM.render stage itself. Something like this:
import * as React from 'react';
import ReactDOM from 'react-dom';
import CssBaseline from '#mui/material/CssBaseline';
import { ThemeProvider } from '#mui/material/styles';
import App from './App';
import theme from './theme';
ReactDOM.render(
<ThemeProvider theme={theme}>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<App />
</ThemeProvider>,
document.querySelector('#root'),
);
Only then will your Material UI components work as you expect.

useState not working in next js with material ui drawer

useState not working. I have searched for a solution I checked many forms like https://github.com/vercel/next.js/issues/7626 , https://github.com/vercel/next.js/issues/17592 ,
Hooks error: Invalid Hook Call using NextJS or ReactJS on Windows , some people seem to suggest that it can be solved by removing a node module that they did not mention the name of, others says it works if they change their webpack configurations but i have never used webpack and couldn't find they mentioned so I am stuck.
I was implementing material ui's drawer, i have created a drawer component and imported it.
Nav.jsx:
import React, { useState } from 'React'
import SignedOutLinks from "./Links/SignedOutLinks"
import { AppBar, Toolbar } from "#material-ui/core"
import MenuBtn from "./Links/MenuBtn"
import Logo from "./Links/Logo"
import CategoryBtn from "./Links/CategoryBtn"
import ShoppingCartBtn from "./Links/ShoppingCartBtn"
import LanguageBtn from "./Links/LanguageBtn"
import DarkModeBtn from "./Links/DarkModeBtn"
import NotificationBtn from "./Links/NotificationBtn"
import SignedIn from "./Links/SignedIn"
import Grid from '#material-ui/core/Grid';
import Search from "./Search/Search"
import { useTheme } from '#material-ui/core/styles';
import useMediaQuery from '#material-ui/core/useMediaQuery';
import Drawer from './Drawer/Drawer'
const signedIn = true
const Nav = () => {
const [isOpened, setIsOpened] = useState(false)
const theme = useTheme()
const isMobile = useMediaQuery(theme.breakpoints.down("sm"))
const handleDrawerToggle = () => {
setIsOpened(!isOpened)
}
return (
<AppBar color="transparent" elevation={0} >
<Toolbar>
{
!isMobile?
<Grid
container
direction="row"
justify="space-between"
alignItems="center"
spacing={10}
>
<Grid item container spacing={5} xs={4} justify="flex-start" wrap="nowrap">
<Grid item>
<Logo/>
</Grid>
<Grid item>
<CategoryBtn />
</Grid>
</Grid>
<Grid item xs={4}>
<Search />
</Grid>
<Grid item container xs={4} justify="flex-end" wrap="nowrap">
<ShoppingCartBtn />
<LanguageBtn />
<DarkModeBtn />
<NotificationBtn />
{signedIn? <SignedIn /> : <SignedOutLinks />}
</Grid>
</Grid>
:
<div>
<Drawer isOpened={isOpened} />
<Grid
container
direction="row"
justify="space-around"
spacing={10}
>
<Grid item container xs={4} justify="flex-start">
<MenuBtn handleClick={handleDrawerToggle} />
</Grid>
<Grid item Container xs={4} justify="center" style={{textAlign: "center"}}>
<Grid item>
<Logo />
</Grid>
</Grid>
<Grid item container xs={4} justify="flex-end">
<ShoppingCartBtn />
</Grid>
</Grid>
</div>
}
</Toolbar>
</AppBar>
)
}
export default Nav
Drawer.jsx:
import { Drawer as MUIDrawer} from '#material-ui/core'
import { List, ListItem,ListItemText, ListItemIcon } from '#material-ui/core'
import NotificationsIcon from '#material-ui/icons/Notifications';
import TranslateIcon from '#material-ui/icons/Translate';
import Brightness4Icon from '#material-ui/icons/Brightness4';
import LocalShippingIcon from '#material-ui/icons/LocalShipping';
import AccountCircleIcon from '#material-ui/icons/AccountCircle';
import BusinessIcon from '#material-ui/icons/Business';
import ExitToAppIcon from '#material-ui/icons/ExitToApp';
import ChatBubbleOutlineIcon from '#material-ui/icons/ChatBubbleOutline';
import CategoryIcon from '#material-ui/icons/Category';
function Drawer({isOpened}) {
const items = [
{
text: user.userName,
icon: <AccountCircleIcon />
},
{
text: "Categories",
icon: <CategoryIcon />
},
{
text: "Language",
icon: <TranslateIcon />
},
{
text: "Mode",
icon: <Brightness4Icon />
},
{
text: "Notifications",
icon: <NotificationsIcon />
},
{
text: "Orders",
icon: <LocalShippingIcon />
},
{
text: "Are You a Seller?",
icon: <BusinessIcon />
},
{
text: "Messages",
icon: <ChatBubbleOutlineIcon />
},
{
text: "Logout",
icon: <ExitToAppIcon />
}
]
return (
<div>
<MUIDrawer open={isOpened}>
<List>
{
items.map(item => {
return (
<ListItem button key={item.text} >
{item.icon && <ListItemIcon>{item.icon}</ListItemIcon>}
<ListItemText primary={item.text} />
</ListItem>
)
})
}
</List>
</MUIDrawer>
</div>
)
}
export default Drawer
Note it was working fine until i coded the Drawer, also useState is imported at the very beginning ing so i didn't forget to import it
Edit:
Folder Structure in next.js
index.js:
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import Nav from '../Components/Navbar/Nav'
export default function Home() {
return (
<>
<Head>
<meta name="description" content="Everything for everyone. TRNC E-commerce website focused on a huge variety of categories from fashion to electronics. Order now and get your product delivered." />
</Head>
<div className={styles.container}>
<Nav />
</div>
</>
)
}
Its finally working, however I couldn't find the problem. I solved it by literaly creating a new component called Nav2 that i copied the same code from the original Nav component from and voila it worked, i deleted the old Nav component and renamed Nav2 to Nav and it kept working.
Note: i found that i forgot to import useContext in the drawer as user is an deconstructed object that is sent from _app.js so i added
const { user } = useContext(UserContext)
to the beginning of the component function

Problem with showing a component which is in another file onclick

I am currently building an website in React with a navigation bar which I use Material-UI for.
My problem is that when I for example click "About" in my navigation bar, I want to show the content/component in About, and when I click Home I want the component Home to be shown and others hidden.
The problem is I am still a beginner in React and want to practice my React skills and now I have the navbar, Home, About in seperate files and not sure on how to pass through state, props and so in this case.
I will show a screen shot on the website and code-snippets to show my code so far.
My website:
File structure of my program:
Here is Code:
App.js:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import NavBar from './Components/Navigationbar'
import Home from './Components/Home'
import About from './Components/About'
class App extends Component {
constructor(props){
super(props);
this.state = {showAbout: true};
this.handleAbout = this.handleAbout.bind(this);
}
handleAbout(){
this.setState({showAbout: true})
}
render() {
return (
<div className="App">
<div className="App-header">
</div>
<NavBar></NavBar>
<p className="App-intro">
<Home></Home>
</p>
{this.state.showAbout ? <About /> : null}
</div>
);
}
}
export default App;
Home.jsx:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Typography from '#material-ui/core/Typography';
const useStyles = makeStyles(theme => ({
root: {
padding: theme.spacing(3, 2),
backgroundColor: 'mistyrose'
},
}));
export default function PaperSheet() {
const classes = useStyles();
return (
<div>
<Paper className={classes.root}>
<Typography variant="h5" component="h3">
Home
</Typography>
<Typography component="p">
Welcome Home
</Typography>
</Paper>
</div>
);
}
About.jsx:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Typography from '#material-ui/core/Typography';
const useStyles = makeStyles(theme => ({
root: {
padding: theme.spacing(3, 2),
backgroundColor: 'mistyrose'
},
}));
export default function PaperSheet() {
const classes = useStyles();
return (
<div>
<Paper className={classes.root}>
<Typography variant="h5" component="h3">
About
</Typography>
<Typography component="p">
About
</Typography>
</Paper>
</div>
);
}
And finally the navigation bar which is from Material UI:
Navigationbar.jsx:
import React from 'react';
import ReactDOM from 'react-dom';
import Button from '#material-ui/core/Button';
import App from '../App';
import { makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Tabs from '#material-ui/core/Tabs';
import Tab from '#material-ui/core/Tab';
import About from './About';
const useStyles = makeStyles({
root: {
flexGrow: 1,
},
});
function handleAbout(props){
alert('About');
}
const navBar = (props) => {
return (
<Paper >
<Tabs
//value={value}
onChange={handleChange}
indicatorColor="primary"
textColor="primary"
centered
>
<Tab label="Home" />
<Tab label="About" onClick={() => handleAbout(props)} />
<Tab label="Contact" />
</Tabs>
</Paper>
);
}
//ReactDOM.render(<navBar />, document.querySelector('#app'));
export default navBar;
My problem is I want to when I click "About" in the navbar, I want to show the About component(the content in About.jsx) on my website but not sure on how to handle state and props in the case when they are in seperate files.
Would appreciate if someone could help me.
Thanks a lot.
You can use react-router for navigation. How to install and use it is quite nicely shown on the page: https://reacttraining.com/react-router/web/guides/quick-start
Oh boy, this is a big one...
In the simplest case, you pass state though props like this:
<ChildComponent showAbout={this.state.showAbout}/>, and access it in ChildComponent by props.showAbout (or this.props.showAbout if it's a class component).
But things can get complicated as your application scales. Values can only be passed through props downwards inside the component tree; in other words, a component can only see a state that's somewhere above it. You can't use state from a sibling component or a component below it.
And that's the whole reason state management libraries exist. They provide a 'global' state that is available anywhere in the app. Redux is one of them.
You should sit down and learn Redux, as you can't really make a big app without a state management tool.
Another thing you should learn is react-router, for client-side routing.
Those things combined will provide a powerful tool for making useful apps.

Material-UI withStyles props in this.props.classes is undefined

I have two React components in a Create React App app, a parent component (App.js) and a child (QuoteMachine.js).
I applied the withStyles HOC API successfully in App.js, but when I used the same format to add one in QuoteMachine.js, passing this.props.classes.card as a property to the Material-UI Card component instance caused a TypeError Cannot read property 'props' of undefined.
Is there a problem with having the withStyles HOC in multiple components? Should I use a ThemeProvider instead?
QuoteMachine.js:
import React from 'react';
import Button from '#material-ui/core/Button';
import Typography from '#material-ui/core/Typography';
import Card from '#material-ui/core/Card';
import CardActions from '#material-ui/core/CardActions';
import CardContent from '#material-ui/core/CardContent';
import './QuoteMachine.css';
import { withStyles } from '#material-ui/core/styles';
const styles = {
card: {
padding: '30px'
}
};
// Parentheses around function body is implicit return
const QuoteMachine = (props) => (
<Card className={this.props.classes.card}>
<CardContent>
{props.isDoneFetching ?
(
<Typography>
<p className="quote">{props.randomQuote().quote}</p>
<p className="author">–{props.randomQuote().author}</p>
</Typography>
) : 'Loading...'}
</CardContent>
<CardActions>
<Button
size="large"
onClick={props.nextRandomQuote}
>
Next
</Button>
</CardActions>
</Card>
)
export default withStyles(styles)(QuoteMachine);
App.js:
import React, { Component } from 'react';
import QuoteMachine from './QuoteMachine';
import 'typeface-roboto'; // From Material-UI
import { Grid } from '#material-ui/core';
import { withStyles } from '#material-ui/core/styles';
import backgroundImage from './dawn.jpg';
const styles = {
// container is root component (set in Grid component instance)
container: {
display: 'flex',
alignItems: 'center',
height: '100vh',
background: `url(${backgroundImage}) center`,
backgroundSize: 'cover', // Using this in background causes issues
}
};
class App extends Component {
constructor(props) {
super(props);
...
}
....
render() {
return (
<Grid
id="quote-box"
className={this.props.classes.container}
justify="center"
container
>
<Grid xs={11} lg={8} item>
<QuoteMachine
isDoneFetching={this.state.isDoneFetching}
randomQuote={this.randomQuote}
nextRandomQuote={this.nextRandomQuote}
/>
</Grid>
</Grid>
);
}
}
export default withStyles(styles)(App);
Since QuoteMachine is a functional component, it doesn't have a this instance and the props are available from the argument to the functional component. You would access the classes like
<Card className={props.classes.card}>

Resources