I have created a navigation drawer which goes something like this,
const Minidrawer = props => {
const itemsList = [
{
text: "Home",
icon: <HomeIcon />,
onClick: () => history.push("/")
},
{
text: "My Cart",
icon: <UserIcon />,
onClick: () => history.push("/auth")
},
{
text: "Register Client",
icon: <GroupAddIcon />,
onClick:() => history.push("/register-client")
},
},
];
return (
<Drawer variant="permanent" open={open}>
<DrawerHeader>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
</IconButton>
</DrawerHeader>
<Divider />
<List>
{itemsList.map((item, index) => {
const { text, icon, onClick } = item;
return (
<ListItem button key={text} onClick={onClick}>
{icon && <ListItemIcon>{icon}</ListItemIcon>}
<ListItemText primary={text} />
</ListItem>
);
})}
</List>
</Drawer>
)}
export default withRouter(Minidrawer);
As you can see I am exporting this in wrapped withRouter because I'm calling browser router main index file
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import { reducers } from './reducers';
import CssBaseline from '#mui/material/CssBaseline';
import { BrowserRouter as Router } from "react-router-dom";
import App from "./App";
const store = createStore(reducer, enhancer);
const rootElement = document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
<Router>
<CssBaseline />
<Provider store={store}><App />
</Provider>
</Router>
</React.StrictMode>,
rootElement
);
My app file where I am importing all the components
import React from "react";
import { Route, Switch } from "react-router-dom";
import Minidrawer from './components/Drawer/Minidrawer'
import { makeStyles } from '#mui/styles';
import Box from '#mui/material/Box';
import Main from "./components/Main/Main";
import {useSelector} from 'react-redux'
const useStyles = makeStyles({
container: {
display: "flex"
}
});
export default function App() {
const classes = useStyles();
const user = useSelector((state) => state.auth);
return (
<Box sx={{ display: 'flex' }}>
<Minidrawer currUser={user}/>
<Main/>
</Box>
);
}
This is my Main component file
import { styled, useTheme } from '#mui/material/styles';
import Box from '#mui/material/Box';
import Typography from '#mui/material/Typography';
import React from 'react';
import { Switch, Route, useHistory} from "react-router-dom";
import { Grid } from '#mui/material';
import Paper from '#mui/material/Paper';
import useStyles from './styles';
import RoutesMaster from "./RoutesMaster";
const RoutesRender = ({ Routes, Key}) => {
const History = useHistory();
console.log(Routes);
if (Routes.AuthRequired) {
History.push('/auth/login');
return null;
} else {
return <Route exact key={Key} path={Routes.Path} render={(props) => <Routes.Component {...props} />} />;
}
};
const Main = (props) => {
const classes = useStyles();
return (
<Box className={classes.box} sx={{ flexGrow: 1 }}>
<Switch>
{RoutesMaster.map((Routes, Index) => (
<RoutesRender Routes={Routes} Key={Index} />
))}
</Switch>
</Box>
)
}
export default Main;
Route Master file,
import Home from '../Home/Home';
import Auth from '../Auth/Auth';
import RegisterClient from '../RegisterClient/RegisterClient'
const RoutesMaster = [
{
Path: '/',
Component: Home,
Title: 'Home',
AuthRequired: false
},{
Path: '/auth',
Component: Auth,
Title: 'Auth',
AuthRequired: false
},{
Path: '/register-client',
Component: RegisterClient,
Title: 'Register Client',
AuthRequired: false
},
]
export default RoutesMaster;
The issue is ,on first load '/' I am getting rendered Home But when on clicking Button links in Mindrawer I can see above on browser URL is changing but the respective component is not getting rendered only getting blank in place of main component
Also one thing to note console.log(Routes); inside RoutesRender in Main.js fn always logs Home "/" path & blank UI
Related
No matter which api I use to navigate, it doesn't take effect, or it reports an error or a blank page. Below is the configuration of my index.js and router.
index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
// import App from './App';
import reportWebVitals from './reportWebVitals';
import 'lib-flexible'
import Router from './router/index';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Router />
</React.StrictMode>
);
reportWebVitals();
router.js:
import React, { useEffect, lazy } from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import "../global.scss";
import NavWrapper from "../components/navs"
const AIPage = lazy(() => import("../pages/AI"))
const BridgePage = lazy(() => import("../pages/Bridge"))
const PipelinePage = lazy(() => import("../pages/Pipeline"))
const BasicRoute = () => {
useEffect(() => {
// console.log(window.location.pathname)
const AIThemes = {
'--app-themeColor': 'linear-gradient(270deg, #64e6c0 0%, #687ff9 100%)',
'--app-border-color': '1px solid #6880F98C',
'--app-background': '#262335'
}
const PipeThemes = {
'--app-themeColor': 'linear-gradient(270deg, #1B74D4 0%, #25BC90 100%)',
'--app-border-color': '1px solid #25BC90',
'--app-background': '#262335'
}
const declaration = document.getElementsByTagName('body')[0].style
if (window.location.pathname === "/pipeline") {
for (let key in PipeThemes) {
declaration.setProperty(key, PipeThemes[key])
}
} else if (window.location.pathname === "/" || window.location.pathname === "/ai") {
for (let key in AIThemes) {
declaration.setProperty(key, AIThemes[key])
}
}
// eslint-disable-next-line
}, [])
return (
<Router>
<NavWrapper />
<Routes>
<Route exact path="/pipeline" element={<PipelinePage />} />
<Route exact path="/AI" element={<AIPage />} />
<Route exact path="/bridge" element={<BridgePage />} />
<Route exact path="/" element={<AIPage />} />
</Routes>
</Router>
)
};
export default BasicRoute;
package.json
"react": "^18.1.0",
"react-router-dom": "^6.3.0",
After the configuration is complete, I have no problem entering the address in the address bar to access, only using the router to navigate has problems.
Using Navlink and Link
import React, { useEffect, useState } from 'react';
import { Link, useNavigate, Navigate, BrowserRouter as Router, NavLink } from "react-router-dom";
import styles from "./index.scss";
import aiGray from '#/assets/images/aiGray.png';
import bridgeGray from '#/assets/images/bridgeGray.png';
import caeGray from '#/assets/images/caeGray.png';
import pipeGray from '#/assets/images/pipeGray.png';
import { LinkOutlined } from '#ant-design/icons';
const ActiveTheme = ({ themeName }) => {
/**
* String- themeName 当前主题名,传入值需与allTheme中匹配项的key相同,用以删除切换项
*/
const navigate = useNavigate()
const allTheme = [
{
icon: aiGray,
link: '/AI',
disabled: false,
key: 'AI'
},
{
icon: pipeGray,
link: '/Pipeline',
disabled: false,
key: 'Pipeline'
},
{
icon: bridgeGray,
link: '/',
disabled: true,
key: 'bridge'
},
{
icon: caeGray,
link: '/',
disabled: true,
key: 'cae'
}
]
const [allThemeList, setAllThemeList] = useState(allTheme)
// useEffect(() => {
// allTheme.forEach((item, ind) => {
// if (item.key === themeName) {
// allTheme.splice(ind, 1)
// }
// })
// setAllThemeList(allTheme)
// // eslint-disable-next-line
// }, [themeName])
const linkTo = (item) => {
console.log(9999999999999)
// --disable-ipc-flooding-protection
navigate(item.link)
}
return (
<div className={styles.routerInner}>
{
allThemeList.map((item, ind) => {
return (
<NavLink to='/Pipeline' end>
<div key={item.key} className={styles.themeIcon} >
<img src={item.icon} alt="" />
</div>
</NavLink>
)
})
}
</div>
)
}
export default ActiveTheme;
The page navigates but it is a blank page, the error is as follows:
"A component suspended while responding to synchronous input."
Using Navigate
<Navigate to='/Pipeline' end>
<div key={item.key} className={styles.themeIcon} >
<img src={item.icon} alt="" />
</div>
</Navigate>
The page reports an error and falls into an infinite loop:
Maximum update depth exceeded.
I don't know where I trigger the useState infinite loop. How should I change the dependencies?
Usi useNavigate
const navigate = useNavigate()
return (
<div className={styles.routerInner}>
{allThemeList.map((item, ind) => {
return (
<div key={item.key} className={styles.themeIcon} onClick={navigate(item.link)}>
<img src={item.icon} alt="" />
</div>
)
})}
</div>
)
The page does not report an error but gives a warning:
`"router.ts:11 You should call navigate() in a React.useEffect(), not when your component is first rendered"'.
I am working with Material-ui. after building the project with npm run build, it shows blank page on running npm run serve
I have tried setting homepage: "./" in the package.json as from here, it's still showing blank page. is it from MUI or am I missing something in my code.
Checking the console in the browser I get this error.
index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import reportWebVitals from "./reportWebVitals";
import { MoralisProvider } from "react-moralis";
import { App } from "./App";
const appID =
process.env.REACT_APP_MORALIS_APP_ID;
const serverUrl =
process.env.REACT_APP_MORALIS_SERVER_URL;
ReactDOM.render(
<React.StrictMode>
<MoralisProvider appId={appID} serverUrl={serverUrl}>
<BrowserRouter>
<App />
</BrowserRouter>
</MoralisProvider>
</React.StrictMode>,
document.getElementById("root")
);
reportWebVitals();
app.js
import Auth from "./components/header";
import Pannel from "./components/bottomNav";
import Profile from "./components/profile";
import Betting from "./components/betting";
import Raffle from "./components/raffle";
// import useMediaQuery from "#mui/material/useMediaQuery";
import { CssBaseline } from "#mui/material";
import { ThemeProvider, createTheme } from "#mui/material/styles";
import React, { useMemo, useState } from "react";
import { Routes, Route } from "react-router-dom";
const ColorModeContext = React.createContext({ toggleColorMode: () => {} });
function App() {
// const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
// prefersDarkMode ? "dark" : "light"
const [mode, setMode] = useState("dark");
const theme = useMemo(
() =>
createTheme({
palette: {
mode,
primary: {
main: "#ffff00",
dark: "#10294c",
},
secondary: {
main: "#ffb400",
},
},
}),
[mode]
);
const colorMode = useMemo(
() => ({
toggleColorMode: () => {
setMode((prevMode) => (prevMode === "light" ? "dark" : "light"));
},
}),
[]
);
return (
<ColorModeContext.Provider value={colorMode}>
<ThemeProvider theme={theme}>
<CssBaseline />
<Auth />
<Routes>
<Route path="/" element={<Profile />} />
<Route path="bet" element={<Betting />} />
<Route path="lottery" element={<Raffle />} />
</Routes>
<Pannel />
</ThemeProvider>
</ColorModeContext.Provider>
);
}
export { App, ColorModeContext };
however it renders properly on local development
i figured this out debugging from the break-point. it turns out that i made use of react useEffects and useEthers from usedapp/core somewhere in my project that raised the reactdom invalid variant error.
a library hook from useEthers was redundant as i did not initialise the web3 provider for my project
I have 3 files:
a root file
an icon file (component)
and an upload file (component)
I want to make sure that when the icon is pressed the upload screen appears.
I added the Router function in the Icon File so that it is connected to the Upload file.
Only when I press it now nothing happens.
How can i fix this ?
The Root file:
import React from 'react';
import './App.css';
import ProcurementAnalysis from "./Pages/ProcurementAnalysis/ProcurementAnalysis";
import Question from "./Components/upload/icon";
function App() {
return (
<React.Fragment>
<ProcurementAnalysis />
<Question />
</React.Fragment>
);
}
export default App;
The Icon file:
import React from 'react';
import { IconContext } from "react-icons";
import { BsFileEarmarkArrowDown } from "react-icons/bs";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import "./icon.css"
const Question = () => {
return (
<IconContext.Provider value={{ color: "Green", className: "Icon", size:"3em" }}>
<BsFileEarmarkArrowDown />
</IconContext.Provider>
);
};
export default function Firms() {
return (
<Router>
<Link to="/"><Question /></Link>
<Switch>
<Route exact path="./Upload.js">
<Question />
</Route>
</Switch>
</Router>,
<Question />
);
}
The upload file
import React from 'react';
class Upload extends React.Component {
render() {
return <h1>Upload</h1>;
}
}
export default Upload
The Icon file:
import React from 'react';
import { IconContext } from "react-icons";
import { BsFileEarmarkArrowDown } from "react-icons/bs";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import "./icon.css"
import Upload from './upload'
const Question = () => {
return (
<IconContext.Provider value={{ color: "Green", className: "Icon", size:"3em" }}>
<BsFileEarmarkArrowDown />
</IconContext.Provider>
);
};
export default function Firms() {
return (
<Router>
<Link to="/"><Question /></Link>
<Switch>
<Route
path='/upload'
render={() => {
return <Upload />;
}}
/>
</Switch>
</Router>,
<Question />
);
}
i geuss the upload is in the sime file path as this file
I am creating a simple react application using material-ui. I am using MuiThemeProvider and ThemeProvider for theme.
App.js
import React from 'react';
import { createMuiTheme, MuiThemeProvider } from '#material-ui/core/styles';
import { ThemeProvider } from '#material-ui/styles';
import { CssBaseline } from '#material-ui/core';
import { Topic } from './dashboard/components/drawer/topic.js'
const theme = createMuiTheme({
palette : {
type : 'dark',
background : {
default : "#000000"
},
secondary : {
main : '#E19A4C'
}
}
})
function App() {
return (
< MuiThemeProvider theme={theme}>
<ThemeProvider theme={theme}>
<CssBaseline />
<div className="App">
<Dashboard />
<Topic />
</div>
</ThemeProvider>
</ MuiThemeProvider>
);
}
export default App;
Topic.js
import React, { Component } from 'react';
import { Typography, makeStyles, Box, Paper } from '#material-ui/core';
const style = makeStyles(theme => ({
paper : {
background : '#ff00ff'
}
}))
export const Topic = (props) => {
const classes = style()
return (
<div>
<Paper className={classes.box}>
<Typography variant="h6" component="h6" gutterBottom>
{props.data}
</Typography>
</Paper>
</div>
)
}
export default Topic
I am getting error Uncaught ReferenceError: theme is not defined
I have tried { withTheme : true } in makeStyles but it doesn't work.
Sending theme as props works but is not recommended.
Can Someone please help?
In your Topic.js file try using useTheme hook like this:
import React, { Component } from 'react';
import { Typography, makeStyles, Box, Paper } from '#material-ui/core';
import { useTheme } from '#material-ui/core/styles';
const style = makeStyles(theme => ({
paper : {
background : '#ff00ff'
}
}))
export const Topic = (props) => {
const classes = style()
const theme = useTheme();
return (
<div>
<Paper className={classes.box}>
<Typography variant="h6" component="h6" gutterBottom>
{props.data}
</Typography>
</Paper>
</div>
)
}
export default Topic
Now you can access the theme you created in App.js from theme variable(e.g const theme)
Problem:
I have created a react application there I am using the private route from react-router-dom and using Lazy loading. This is my index.js file.
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { PrivateRoute } from "./components/PrivateRoute/PrivateRoute";
import SignIn from "./components/SignIn/SignIn";
import AdminLayout from "./components/Admin/AdminLayout/AdminLayout";
import OfficerLayout from "./components/Officer/OfficerLayout/OfficerLayout";
import * as serviceWorker from "./serviceWorker";
import { Provider } from "react-redux";
import { createLogicMiddleware } from "redux-logic";
import { createStore, applyMiddleware, compose } from "redux";
import { Route, Switch, BrowserRouter } from "react-router-dom";
import "primereact/resources/themes/nova-light/theme.css";
import "primereact/resources/primereact.min.css";
import "primeicons/primeicons.css";
import reducers from "./reducers";
import services from "./services";
const logicMiddleware = createLogicMiddleware(services, {});
const middleware = applyMiddleware(logicMiddleware);
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const enhancer = composeEnhancers(middleware);
let store = createStore(reducers, enhancer);
// let store = applyMiddleware(promiseMiddeleware)(createStore);
ReactDOM.render(
// <Provider
// store={store(
// reducers,
// window.__REDUX_DEVTOOLS_EXTENSION__ &&
// window.__REDUX_DEVTOOLS_EXTENSION__()
// )}
// >
<Provider store={store}>
<BrowserRouter>
<Switch>
<Route exact path="/" component={SignIn} />
<Route path="/signin" component={SignIn} />
<PrivateRoute
exact
path="/admin"
name="Admin"
component={AdminLayout}
></PrivateRoute>
<PrivateRoute
exact
path="/officer"
name="Officer"
component={OfficerLayout}
></PrivateRoute>
</Switch>
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
This is my private route component.
import React, { Component } from "react";
import { Redirect, Route } from "react-router-dom";
export const PrivateRoute = ({ component: Component, ...rest }) => (
<Route
{...rest}
render={props =>
localStorage.getItem("jwt") ? (
<Component {...props}></Component>
) : (
<Redirect
to={{
pathname: "/",
state: { from: props.location }
}}
></Redirect>
)
}
></Route>
);
This is my officer layout component.
import React, { Component, Suspense } from "react";
import { Redirect, Route, Switch } from "react-router-dom";
import routes from "../officer_routes";
import "./OfficerLayout.css";
import { Container, Card, Row, Col } from "reactstrap";
const OfficerHeader = React.lazy(() =>
import("../OfficerHeader/OfficerHeader")
);
class OfficerLayout extends Component {
loading = () => (
<div className="animated fadeIn pt-1 text-center">Loading...</div>
);
componentDidMount() {
document.body.classList.add("officer-layout-background");
}
componentWillUnmount() {
document.body.classList.replace("background-color", "no-color");
}
render() {
return (
<div>
<Container fluid>
<div className="app-panel">
<div className="police-app-header">
<Suspense fallback={this.loading()}>
<OfficerHeader />
</Suspense>
</div>
<Row>
<Col lg="1" />
<Col lg="10">
<Card className="police-app-panel-card">
{" "}
<Suspense fallback={this.loading()}>
<Switch>
{routes.map((route, idx) => {
return route.component ? (
<Route
key={idx}
path={route.path}
exact={route.exact}
name={route.name}
render={props => <route.component {...props} />}
/>
) : null;
})}
<Redirect from="/officer" to="/officer/doFine" />
</Switch>
</Suspense>{" "}
</Card>
</Col>
<Col lg="1" />
</Row>
</div>
</Container>
{/* <footer className="police-app-footer">iiii</footer> */}
</div>
);
}
}
export default OfficerLayout;
This is my officer routes.
import React from "react";
const OfficerPanel = React.lazy(() => import("./OfficerPanel/OfficerPanel"));
const EnforcedFines = React.lazy(() => import("./EnforcedFines/EnforcedFines"));
const DriverList = React.lazy(() => import("./DriverList/DriverList"));
const FineSearchSingle = React.lazy(() =>
import("./FineSearchSingle/FineSearchSingle")
);
const DriverDetails = React.lazy(() => import("./DriverDetails/DriverDetails"))
const Profile = React.lazy(()=> import("./Profile/Profile"))
const ChangePassword = React.lazy(() => import("./Profile/ChangePassword/Changepassword"))
const routes = [
{ path: "/officer/findDriver", name: "findDriver", component: DriverList },
{
path: "/officer/singleFine/:id",
name: "SingleFine",
component: FineSearchSingle
},
{
path: "/officer/driverDetails/:id",
name: "Driver Details",
component: DriverDetails
},
{
path: "/officer/profile",
name: "Profile",
component: Profile
},
{
path: "/officer/changePassword",
name: "Change Password",
component: ChangePassword
}
];
export default routes;
The private route is working correctly It means when the user is not login to system it redirects to the login page. But routes like /officer/findDriver does not redirect correctly. Can someone help me to solve this issue? Thank you