React app display blank page without any compilation error - javascript

I am not sure what went wrong with my react app below, it compile successfully without error but doesn't show anything (just show a blank page). Can anyone point out what went wrong with my code? Sorry I am new to react.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css'
import { BrowserRouter } from 'react-router-dom'
import App from './App';
ReactDOM.render((
// <Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
// </Provider>
), document.getElementById('root'))
App.js
import { BrowserRouter as Router, Route, Link, NavLink } from "react-router-dom";
import Home from "./components/Home";
import NewBuilding from "./components/NewBuilding";
import React, { Component } from "react";
import Web3 from 'web3';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import "./App.css";
import { useEffect, useState } from 'react';
function App() {
const [currentAccount, setCurrentAccount] = useState(null);
const checkWalletIsConnected = async () => {
const { ethereum } = window;
if (!ethereum) {
console.log("Make sure you have Metamask installed!");
return;
} else {
console.log("Wallet exists! We're ready to go!")
}
const accounts = await ethereum.request({ method: 'eth_accounts' });
if (accounts.length !== 0) {
const account = accounts[0];
console.log("Found an authorized account: ", account);
setCurrentAccount(account);
} else {
console.log("No authorized account found");
}
}
const connectWalletHandler = async () => {
const { ethereum } = window;
if (!ethereum) {
alert("Please install Metamask!");
}
try {
const accounts = await ethereum.request({ method: 'eth_requestAccounts' });
console.log("Found an account! Address: ", accounts[0]);
setCurrentAccount(accounts[0]);
} catch (err) {
console.log(err)
}
}
const connectWalletButton = () => {
return (
<button onClick={connectWalletHandler} className='cta-button connect-wallet-button'>
Connect Wallet
</button>
)
}
useEffect(() => {
checkWalletIsConnected();
}, [])
return (
<div>
<Router>
<AppBar position="static" color="default" style={{ margin: 0 }}>
<Toolbar>
<Typography variant="h6" color="inherit">
<NavLink className="nav-link" to="/">Home</NavLink>
</Typography>
<NavLink className="nav-link" to="/new/">New</NavLink>
</Toolbar>
</AppBar>
<Route path="/" exact component={Home} />
<Route path="/new/" component={NewBuilding} />
</Router>
</div>
)
}
export default App;
My Home.js is residing in a components folder
The folder structure is as below
Home.js
import React, { useState, useEffect } from "react";
import { makeStyles } from '#material-ui/core/styles';
import Web3 from 'web3'
const useStyles = makeStyles(theme => ({
button: {
margin: theme.spacing(1),
},
input: {
display: 'none',
},
}));
const Home = () => {
const classes = useStyles();
const [ contract, setContract] = useState(null)
const [ accounts, setAccounts ] = useState(null)
const [ funds, setFunds ] = useState([])
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'))
useEffect(() => {
}, []);
return (
<div><h2>Home</h2></div>
)
}
export default Home;

Your Route component should have the prop element instead of component, see the migration guide.
<Route path="/" exact element={<Home />} />
In App.js you're wrapping your components again in a Router. Instead you should wrap your Route components in a Routes.
import { Routes, Route, Link, NavLink } from "react-router-dom";
...
<div>
<AppBar position="static" color="default" style={{ margin: 0 }}>
<Toolbar>
<Typography variant="h6" color="inherit">
<NavLink className="nav-link" to="/">
Home
</NavLink>
</Typography>
<NavLink className="nav-link" to="/new/">
New
</NavLink>
</Toolbar>
</AppBar>
<Routes>
<Route path="/" exact element={<Home />} />
<Route path="/new/" element={<NewBuilding />} />
</Routes>
</div>

Related

Nested Router in ReactJS - Show blank page on refresh

I am a beginner in ReactJS and React Router and I am having some issues with my nested router.
For my main router in App.js, things work well. So I can visit my landing page (/), login page (/login), and register page (/register). And once I reach this page, if I do a manual refresh on my Chrome Browser (ctrl r), the page refresh and render accordingly.
Below is my App.js
import React from "react";
import { Router, Switch } from "react-router-dom";
import Login from "./components/Login";
import Register from "./components/Register";
import Dashboard from "./components/Dashboard";
import DynamicLayout from './router/DynamicLayout';
import LandingPage from './components/homepage/LandingPage';
import { history } from "./helpers/history";
const App = () => {
return (
<Router history={history}>
<div className="App">
<Switch>
<DynamicLayout
exact
path="/"
component={LandingPage}
layout="LANDING_NAV"
/>
<DynamicLayout
exact
path="/login"
component={Login}
layout="LOGIN_PAGE"
/>
<DynamicLayout
exact
path="/register"
component={Register}
layout="REGISTER_PAGE"
/>
<DynamicLayout
path="/dashboard"
component={Dashboard}
layout="DASHBOARD_PAGE"
/>
</Switch>
</div>
</Router>
);
};
export default App;
Below is my DynamicLayout.js
import React from "react";
import { BrowserRouter as Route, Switch } from "react-router-dom";
import Login from "../components/Login";
import Register from "../components/Register";
const DynamicLayout = (props) => {
const { component: RoutedComponent, layout, ...rest } = props;
const actualRouteComponent = <RoutedComponent {...props} />;
switch (layout) {
case "LANDING_NAV": {
return <div>{actualRouteComponent}</div>;
}
case "LOGIN_PAGE": {
return <div>{actualRouteComponent}</div>;
}
case "REGISTER_PAGE": {
return <div>{actualRouteComponent}</div>;
}
case "DASHBOARD_PAGE": {
return <div>{actualRouteComponent}</div>;
}
default: {
return (
<div>
<h2>Default Nav</h2>
{actualRouteComponent}
</div>
);
}
}
};
export default DynamicLayout;
The issue is with my nested router which is in my Dashboard component. Basically, once a admin user logged in, they will be shown the admin dashboard.
Below is my Dashboard component.
import React, { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { useDispatch } from "react-redux";
import { history } from "../helpers/history";
import { useHistory } from 'react-router-dom';
import {
BrowserRouter as Router,
Route,
Switch,
} from "react-router-dom";
import { logout } from "../actions/auth";
import AdminSideNavBar from "../components/admin/AdminSideNavBar";
import AdminManageUsers from "./admin/AdminManageUsers";
import AdminPendingApprovalUsers from "../components/admin/AdminPendingApprovalUsers";
import AdminDeactivatedUsers from "./admin/AdminDeactivatedUsers";
import AdminRegisterInternalUsers from "./admin/AdminRegisterInternalUsers";
import AdminLogs from "../components/admin/AdminLogs";
import BrokerSideNavBar from "../components/broker/BrokerSideNavBar";
import ShareholderSideNavBar from "../components/shareholder/ShareholderSideNavBar";
import Login from "../components/Login"
import AdminActivatedUsers from "./admin/AdminActivatedUsers";
const Dashboard = () => {
const [showAdminDashboard, setShowAdminDashboard] = useState(false);
const [showBrokerDashboard, setShowBrokerDashboard] = useState(false);
const [showShareholderDashboard, setShowShareholderDashboard] =
useState(false);
const { user: currentUser } = useSelector((state) => state.auth);
const dispatch = useDispatch();
useEffect(() => {
if (currentUser) {
setShowAdminDashboard(currentUser.roles.includes("ROLE_ADMIN"));
setShowBrokerDashboard(currentUser.roles.includes("ROLE_BROKER"));
setShowShareholderDashboard(
currentUser.roles.includes("ROLE_SHAREHOLDER")
);
}
}, [currentUser]);
const logOut = () => {
dispatch(logout());
};
let history = useHistory();
return (
<div>
{showAdminDashboard && (
<Router history= {history}>
<div className="wrapper">
<AdminSideNavBar />
<Switch>
<Route exact path="/dashboard" component={AdminPendingApprovalUsers} />
<Route exact path="/logs" component={AdminLogs} />
<Route exact path="/manageusers" component={AdminManageUsers} />
<Route exact path="/activeusers" component={AdminActivatedUsers} />
<Route exact path="/deactivatedusers" component={AdminDeactivatedUsers} />
<Route exact path="/registerinternalusers" component={AdminRegisterInternalUsers} />
</Switch>
</div>
</Router>
)}
{showBrokerDashboard && <BrokerSideNavBar />}
{showShareholderDashboard && <ShareholderSideNavBar />}
</div>
);
};
export default Dashboard;
With my side nav bar (AdminSideNavbar component), I can navigate to the various pages. Like /logs, /manageusers, /activeusers etc.
Below is my AdminSideNavBar component
import React from "react";
import { useSelector } from "react-redux";
import { useDispatch } from "react-redux";
import { logout } from "../../actions/auth";
import {
CDBSidebar,
CDBSidebarContent,
CDBSidebarFooter,
CDBSidebarHeader,
CDBSidebarMenu,
CDBSidebarMenuItem,
} from "cdbreact";
import { NavLink } from "react-router-dom";
const AdminSideNavBar = () => {
const { user: currentUser } = useSelector((state) => state.auth);
const dispatch = useDispatch();
const { isLoggedIn } = useSelector((state) => state.auth);
const logOut = () => {
dispatch(logout());
};
return (
<div className="stickysidenav">
<CDBSidebar textColor="#fff" backgroundColor="#333">
<CDBSidebarHeader prefix={<i className="fa fa-bars fa-large"></i>}>
<a
href="/"
className="text-decoration-none"
style={{ color: "inherit" }}
>
TradeDuh
</a>
<p>{currentUser.username}</p>
{/* {isLoggedIn && (
<div className="wrapper">
<p>{currentUser.username}</p>
</div>
)} */}
</CDBSidebarHeader>
<CDBSidebarContent className="sidebar-content">
<CDBSidebarMenu>
<NavLink exact to="/dashboard" activeClassName="activeClicked">
<CDBSidebarMenuItem icon="columns">Dashboard</CDBSidebarMenuItem>
</NavLink>
<NavLink exact to="/logs" activeClassName="activeClicked">
<CDBSidebarMenuItem icon="table">Logs</CDBSidebarMenuItem>
</NavLink>
<NavLink exact to="/uploadcompany" activeClassName="activeClicked">
<CDBSidebarMenuItem icon="edit">Update Nasdaq Stocks</CDBSidebarMenuItem>
</NavLink>
<NavLink exact to="/manageusers" activeClassName="activeClicked">
<CDBSidebarMenuItem icon="users-cog">Manage Users</CDBSidebarMenuItem>
</NavLink>
<NavLink exact to="/activeusers" activeClassName="activeClicked">
<CDBSidebarMenuItem icon="user-check">Active Users</CDBSidebarMenuItem>
</NavLink>
<NavLink exact to="/deactivatedusers" activeClassName="activeClicked">
<CDBSidebarMenuItem icon="user-times">De-activated Users</CDBSidebarMenuItem>
</NavLink>
<NavLink to="/registerinternalusers" activeClassName="activeClicked">
<CDBSidebarMenuItem icon="user-plus">
Add Internal Users
</CDBSidebarMenuItem>
</NavLink>
<NavLink
exact
to="/login"
activeClassName="activeClicked"
onClick={logOut}
>
<CDBSidebarMenuItem icon="sign-out-alt">
Log Out
</CDBSidebarMenuItem>
</NavLink>
</CDBSidebarMenu>
</CDBSidebarContent>
<CDBSidebarFooter style={{ textAlign: "center" }}>
<div
style={{
padding: "20px 5px",
}}
>
TradeDuh (FDM - S21-Java-02)
</div>
</CDBSidebarFooter>
</CDBSidebar>
</div>
);
};
export default AdminSideNavBar;
The issue is, once I reach the various page, if I do a manual refresh (ctrl r), my whole screen will turn white/blank.
So say if I click on /logs, AdminLogs component is rendered, which is all good. BUT... if I now press ctrl r to do a manual fresh, the AdminLogs component don't show anymore. All I see is a blank white screen.
This is totally different from what is happening in my main router where I can do a manual page fresh and the page will render accordingly.
Any idea on how to solve this? What is my issue here?
Thank you for the help!

Unable to redirect on button click React.js (using context provider)

I'm new to React and I've been trying to redirect to a different component after getting a response from my API.
I've tried using history, location, and Redirect, but the redirect never happens.
Also, I get undefined when using all of the above.
I'm not sure if this is because my App is defined outside the Router, if it is the reason I'm still unable to fix the issue.
Here is my code:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { AppProvider } from './Context'
import { BrowserRouter as Router } from 'react-router-dom'
ReactDOM.render(
<React.StrictMode>
<AppProvider>
<App />
</AppProvider>
</React.StrictMode>,
document.getElementById('root')
);
App.js
import React from 'react';
import './App.css';
import {Home, JoinRoom, CreateRoom, Room } from './pages';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
function App() {
return (
<div className="App">
<Router>
<Switch>
<Route path="/" exact={true}>
<Home />
</Route>
<Route path="/join">
<JoinRoom />
</Route>
<Route path="/create">
<CreateRoom />
</Route>
<Route path="/room/:roomCode">
<Room />
</Route>
</Switch>
</Router>
</div>
);
}
export default App;
Context.js
Here, in the handleRoomButtonPressed, I'm getting data from the API and trying to redirect.
import React, { useState, useContext } from 'react';
import axios from 'axios';
import { Redirect, useHistory } from "react-router-dom";
const AppContext = React.createContext()
const AppProvider = ({ children }) => {
// const history = useHistory();
const [guestCanPause, setGuestCanPause] = useState(true);
const [votesToSkip, setVotesToSkip] = useState(2);
const [isHost, setIsHost] = useState(false);
const handleVotesChange = (e) => {
e.preventDefault();
setVotesToSkip(e.target.value);
}
const handleGuestCanPauseChange = (e) => {
e.preventDefault();
setGuestCanPause(e.target.value)
}
const handleRoomButtonPressed = async (props) => {
const roomData = { guest_can_pause: guestCanPause, votes_to_skip: votesToSkip };
const response = await axios.post('/api/create-room/', roomData);
console.log(response.data)
const redirectUrl = "/room/" + response.data.code;
console.log(props)
return <Redirect to={redirectUrl} />
}
const getRoomDetails = async (roomCode) => {
axios
.get("/api/get-room?code=" + roomCode)
.then((res) => {
console.log(res.data)
setVotesToSkip(res.data.votes_to_skip);
setGuestCanPause(res.data.guest_can_pause);
setIsHost(res.data.is_host);
})
.catch((err) => console.log(err));
}
return <AppContext.Provider value={{ guestCanPause,
votesToSkip,
isHost,
handleGuestCanPauseChange,
handleVotesChange,
handleRoomButtonPressed,
getRoomDetails, }}>
{children}
</AppContext.Provider>
}
export const useGlobalContext = () => {
return useContext(AppContext)
}
export { AppContext, AppProvider }
The onClick is called in CreateRoom.js
import React, { useState, } from 'react';
import { useGlobalContext } from '../Context'
import { Link } from 'react-router-dom';
import { Button, Grid, Typography, TextField, FormHelperText, FormControl, Radio, RadioGroup, FormControlLabel } from '#material-ui/core'
function CreateRoom() {
const defaultVotes = 2;
const { handleGuestCanPauseChange, handleVotesChange, handleRoomButtonPressed } = useGlobalContext();
return (
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography component="h4" variant="h4">
Create A Room
</Typography>
</Grid>
<Grid item xs={12} align="center">
<FormControl component="fieldset">
<FormHelperText>
<div align="center">Guest Control of Playback state</div>
</FormHelperText>
<RadioGroup row defaultValue="true" onChange={handleGuestCanPauseChange}>
<FormControlLabel value="true"
control={<Radio color="primary" />}
label="Play/Pause" labelPlacemment="bottom" />
<FormControlLabel value="false"
control={<Radio color="secondary" />}
label="No Control" labelPlacemment="bottom" />
</RadioGroup>
</FormControl>
</Grid>
<Grid item xs={12} align="center">
<FormControl>
<TextField required={true}
type="number" onChange={handleVotesChange}
defaultValue={defaultVotes}
inputProps={{ min: 1,
style: { textAlign: "center" },
}}
/>
<FormHelperText>
<div align="center">Votes Required To Skip Song</div>
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} align="center">
<Button
color="primary"
variant="contained"
onClick={handleRoomButtonPressed}
>
Create A Room
</Button>
</Grid>
<Grid item xs={12} align="center">
<Button color="secondary" variant="contained" to="/" component={Link}>
Back
</Button>
</Grid>
</Grid>
)
}
export default CreateRoom
If I understood a subject correctly your AppProvider is located above the router in the component tree. Thus, the react router cannot inject its dependencies into your AppProvider. If you want to access react-router API, such as useHistory hook or others, you should call it from one of the Router children, then it will works.

Login Form React JS With Custom Hook

I'm currently in the process of learning React JS.Tutorial D.O
I already have a PHP backend before and I want to create a login form where the result of the backend is JWT.
I use a custom hook in React JS for that.
Here is the code that I created.
App.js
import "./App.css";
import React from "react";
import { Routes } from "../config";
import { useToken } from "../hooks";
import Login from "./Login";
const App = () => {
const { token, setToken } = useToken();
if (!token) {
return <Login setToken={setToken} />;
}
return <Routes />;
};
export default App;
useToken()
import { useState } from "react";
export default function useToken() {
const getToken = () => {
const tokenString = localStorage.getItem("token");
const userToken = JSON.parse(tokenString);
return userToken?.token;
};
const [token, setToken] = useState(getToken());
const saveToken = (userToken) => {
localStorage.setItem("token", JSON.stringify(userToken));
setToken(userToken.token);
};
return {
setToken: saveToken,
token,
};
}
Login/index.js
import React, { useState } from "react";
import PropTypes from "prop-types";
import { Button, Card, Col, Container, Form, Row } from "react-bootstrap";
import "./login.css";
async function loginUser(credentials) {
const url = "v1/auth";
const user = new FormData();
user.append("username", credentials.username);
user.append("password", credentials.password);
return fetch(url, {
method: "POST",
body: user,
}).then((data) => data.json());
}
export default function Login({ setToken }) {
const [username, setUserName] = useState();
const [password, setPassword] = useState();
// Handle submit
const handleSubmit = async (e) => {
e.preventDefault();
const token = await loginUser({ username, password });
setToken(token);
};
return (
<div id="login-page">
<Container>
<Row className="d-flex justify-content-md-center align-items-center vh-100">
<Col sm={12} md={6}>
<Card>
<Form onSubmit={handleSubmit}>
<Card.Header>Sign In</Card.Header>
<Card.Body>
<Form.Group controlId="loginform-username">
<Form.Label>Username</Form.Label>
<Form.Control
type="text"
placeholder="Username"
name="username"
onChange={(e) => setUserName(e.target.value)}
/>
</Form.Group>
<Form.Group controlId="loginform-password">
<Form.Label>Password</Form.Label>
<Form.Control
name="password"
type="password"
placeholder="Password"
onChange={(e) => setPassword(e.target.value)}
/>
</Form.Group>
</Card.Body>
<Card.Footer>
<Button
variant="primary"
type="submit"
className="float-right"
>
Login
</Button>
<div className="clearfix"></div>
</Card.Footer>
</Form>
</Card>
</Col>
</Row>
</Container>
</div>
);
}
Login.propTypes = {
setToken: PropTypes.func.isRequired,
};
When I login successfully, I save the token to local storage. But I got the following warning.
index.js:1 Warning: Failed prop type: The prop `setToken` is marked as required in `Login`, but its value is `undefined`.
How to solve this?. Any help it so appreciated
Updated
Routes
import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { Login, Home } from "../../pages";
const Routes = () => {
return (
<Router>
<Switch>
<Route path="/login">
<Login />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Router>
);
};
export default Routes;
In Routes you call Login but never pass it setToken, which is required. One option is to pass the setToken function down through Routes:
App.js
import "./App.css";
import React from "react";
import { Routes } from "../config";
import { useToken } from "../hooks";
import Login from "./Login";
const App = () => {
const { token, setToken } = useToken();
if (!token) {
return <Login setToken={setToken} />;
}
return <Routes setToken={setToken} />;
};
export default App;
Routes.js
import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { Login, Home } from "../../pages";
const Routes = ({ setToken }) => {
return (
<Router>
<Switch>
<Route path="/login">
<Login setToken={setToken} />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Router>
);
};
export default Routes;
<Route path="/login">
<Login /> /* <--- this line is calling Login component but is passing setToken as undefined */
</Route>

The URL with parameters in react app does not work in new browser window or tab

I have react-App with redux using Asp.netWebApi as back-end. The site has tutors.jsx and tutorDetails.jsx components. When the user clicks on the tutors list in tutors.jsx component , the tutorDetails.jsx component displays.
The link has two parameters in url tutorId and fullName. like
https://www.virtualcollege.pk/TutorDetails/1105/Sohail%20Anjum
The problem is that when we copy the url and open it in a new browser tab, it does not work.
here is live link for tutors:
tutors list live link
Here is the live link for detail page: the tutorsDetails page live link
Here is code for tutorDetails.jsx component
import React, { useState, useEffect } from "react";
import { makeStyles } from '#material-ui/core/styles';
import {useDispatch,useSelector} from 'react-redux';
import { Link,useParams} from 'react-router-dom';
import * as actions from "../_actions/tutorActions";
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';
const useStyles = makeStyles({
title: {
fontSize: 14,
display: 'flex',
},
pos: {
marginBottom: 12,
},
card: {
padding:10,
marginTop:10,
display: 'flex',
flex:1,
},
cardAction: {
display: 'block',
textAlign: 'initial'
},
cardMedia: {
width: 160,
},
});
export default function TutorDetails(props) {
const [loading, setLoading] = useState(true);
let {tutorId}=useParams(); // get tutorId from url parameter
let {fullName}=useParams();// get fullname from parameter
const dispatch = useDispatch();
const classes = useStyles();
const tutor = useSelector(state=>state.tutor.list)
useEffect(() => {
//call the action creator with dispatch
// and wait until the promise resolves
actions
.fetchById(tutorId)(dispatch)
setLoading(false);
}, []);
return (
<div>{loading === true ? <span>Loading ! Please waite...</span>:<div>
<Card className={classes.card} variant="outlined">
<CardContent>
<Typography variant="h5" component="h2">
{tutor[0].fullName} <br/>
</Typography>
<Typography variant="h5" component="h2">
{tutor[0].Qualification}
</Typography>
<Typography className={classes.title} color="textSecondary" gutterBottom>
category: {tutor[0].category}
</Typography>
<Typography variant="body2" component="p">
experience:{tutor[0].experience}<br/>
subject: {tutor[0].subject}<br/>
Mobile: 0343-3969030<br/>
email: virtualcollegepk01#gmail.com<br/>
city: {tutor[0].city}<br/>
</Typography>
</CardContent>
</Card>
</div>}
</div>
);
}
Here is the link of url in tutors.jsx component.
<Link to={`/TutorDetails/${record.tutorId}/${record.fullName}`}
> {record.fullName}</Link>
Here is the router link in App.js
<Route path="/TutorDetails/:tutorId/:fullName" component={TutorDetails} />
the App.js component is as below:
import React, { useEffect } from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { history } from '../_helpers';
import { alertActions } from '../_actions/alert.actions';
import { PrivateRoute} from '../_components/PrivateRoute';
import {TeacherCourses} from '../_components/TeacherCourses';
import TutorDetails from '../_components/TutorDetails';
import Tutors from '../_components/Tutors';
import { HomePage } from '../HomePage';
import { Container } from "#material-ui/core";
import { ThemeProvider } from '#material-ui/core/styles'
import CssBaseline from '#material-ui/core/CssBaseline'
import theme from '../theme'
import { ToastProvider} from "react-toast-notifications";
import NewNavbar from "../_components/Header/NewNavbar";
import Footer from "../_components/Header/Footer";
import {carousel} from "react-responsive-carousel/lib/styles/carousel.min.css";
function App() {
const alert = useSelector(state => state.alert);
const dispatch = useDispatch();
useEffect(() => {
history.listen((location, action) => {
// clear alert on location change
dispatch(alertActions.clear());
});
}, []);
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<ToastProvider autoDismiss={true}>
<Container maxWidth="lg">
{alert.message &&
<div className={`alert ${alert.type}`}>{alert.message}</div>
}
<Router history={history}>
<div>
<NewNavbar/>
<Switch>
<Route path="/TutorDetails/:tutorId/:fullName" component= {TutorDetails} />
<Route path="/Tutors" component= {Tutors} />
<Route path="/MyCourses/:tutorId/" component= {MyCourses} />
<Route path="/Enroll/:courseId/:courseTitle" component={Enroll} />
<Route path="/" component={HomePage} />
<Redirect from="*" to="/" />
</Switch>
<Footer/>
</div>
</Router>
</Container>
</ToastProvider>
</ThemeProvider>
);
}
export {App} ;

Cannot set property 'props' of undefined

I'm having an issue with the code
TypeError: Cannot set property 'props' of undefined
i think i did everything right. I even referenced
react cannot set property of props of undefined
and
React-router: TypeError: Cannot set property 'props' of undefined
was unable to figure out the error.
import React from 'react';
import {BrowserRouter as Router, Route, Link} from "react-router-dom";
import signUp from './signUp';
import signIn from './signIn';
import Users from './Users';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import Button from '#material-ui/core/Button';
import {withStyles} from '#material-ui/core';
import Dashboard from './dashBoard';
import { connect } from 'react-redux';
import { createBrowserHistory } from 'history';
import PropTypes, { func, bool, string} from 'prop-types';
export const history = createBrowserHistory({forceRefresh: true});
const styles = {
// This group of buttons will be aligned to the right
rightToolbar: {
color: '#fff',
textDecoration: 'none',
a: {
color: '#fff'
}
},
rightt: {
marginLeft: 'auto',
marginRight: 24
},
root: {
flexGrow: 1
},
menuButton: {
marginRight: 16,
marginLeft: -12
}
};
const logout = (e) => {
e.preventDefault();
localStorage.removeItem('JWT');
};
const Navbar = ({classes, props}) => (
<Router history={history}>
<div className={classes.root}>
<AppBar position="static" className={classes.navbar}>
<Toolbar>
<IconButton color="inherit" aria-label="Menu">
<MenuIcon/>
</IconButton>
<Typography variant="h6" color="inherit">
Eli App
</Typography>
<Typography classcolor="inherit" className={classes.rightt}>
{!props.token && (
<Button>
<Link to="/signUp" className={classes.rightToolbar} >
Sign Up
</Link>
</Button>
)}
<Button>
<Link to="/users" className={classes.rightToolbar}>
Users
</Link>
</Button>
<Button>
<Link to="/dashboard" className={classes.rightToolbar}>
Dashboard
</Link>
</Button>
<Button
onClick={logout}
>
<Link className={classes.rightToolbar} to={'/'}>
LogOut
</Link>
</Button>
</Typography>
</Toolbar>
</AppBar>
<Route path="/signUp" component={signUp}/>
<Route path="/signIn" component={signIn}/>
<Route path="/users" component={Users}/>
<Route path="/dashboard" component={Dashboard}/>
<Route path="/signOut"/>
</div>
</Router>
);
const mapStateToProps = (state) => ({
token: state.user.getToken
})
const mapDispatchToProps = (dispatch) => ({
// logIn: (user) => dispatch(logIn(user))
});
Navbar.propTypes = {
token:PropTypes.string,
}
// export default withStyles(styles)(Navbar);
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles))(Navbar);
updated
Th values you are deconstructing in your function's arguments are already your props, if you want to access your token, you can do the following :
const Navbar = ({classes, token}) => ( //classes and token are INSIDE your props
In the render function :
{!token && (
It seems like the problem could also come from your export :
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles))(Navbar);
You should use compose to use multiple HOC together :
import { compose } from 'redux'
//....
export default compose(connect(mapStateToProps, mapDispatchToProps), withStyles(styles))(Navbar);
You may also experience some unexpected behavior when using a stateless function with redux, I suggest also using the solution from #Shalini Sentiya.
Try to using the navbar react class instead of the function
class Navbar extends Component {
constructor(props){
super(props);
}
render() {
const { token } = this.props;
return (
<Router history={history}>
// your code
{!token && (
<Button>
<Link to="/signUp" className={classes.rightToolbar} >
Sign Up
</Link>
</Button>
)}
// your code
</Router>
);
}
}
const mapStateToProps = (state) => ({
token: state.user.getToken
})
const mapDispatchToProps = (dispatch) => ({
// logIn: (user) => dispatch(logIn(user))
});
Navbar.propTypes = {
token:PropTypes.string,
}
// export default withStyles(styles)(Navbar);
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles))(Navbar);

Categories