How can I put a random component in React JS? - javascript

So, I am trying to put a random component when the user refresh the page web. How can I do it? I created my components and tried to use it like an array but it shows the index of the array when i refresh the page. For example only show 0, 1 or 2 because I have 3 items in my DATA array. Could you help me please? Thank you so much!!!
import React, { useEffect, useState } from 'react';
import './App.css';
import Enterprice from './components/pages/Enterprice';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Developers from './components/pages/Developers';
import Community from './components/pages/Community';
import Download from './components/pages/Download';
import SignUp from './components/pages/SignUp';
import Marketing from './components/pages/Marketing';
import Consulting from './components/pages/Consulting';
import Navbar from './components/navbar/Navbar';
import { MainFrontOne } from './components/ui/mainFront/mainFrontOne/MainFrontOne';
import { MainFrontTwo } from './components/ui/mainFront/mainFrontTwo/MainFrontTwo';
import { MainFrontThree } from './components/ui/mainFront/mainFrontThree/MainFrontThree';
function App() {
const data =[
<MainFrontOne/>, <MainFrontTwo/>, <MainFrontThree/>
]
const [mainFrontRandom, setMainFrontRandom] = useState(null);
const compDisplay = ()=>{
const randomDisplay = Math.floor(Math.random()*data.length);
setMainFrontRandom(randomDisplay)
}
useEffect(() => {
compDisplay()
}, [])
return (
<>
<BrowserRouter>
<Navbar />
{/* <MainFrontOne/> */}
{/* <MainFrontTwo/> */}
{/* <MainFrontThree/> */}
{
mainFrontRandom
}
<Routes>
<Route path="/" element={<Enterprice />}/>
<Route path="enterprice" element={<Enterprice />}/>
<Route path="developers" element={<Developers />}/>
<Route path="community" element={<Community />}/>
<Route path="download" element={<Download />}/>
<Route path="sign-up" element={<SignUp />}/>
<Route path="marketing" element={<Marketing />}/>
<Route path="consulting" element={<Consulting />}/>
</Routes>
</BrowserRouter>
</>
);
}
export default App;
This is my third component and the others are similar.
import React from 'react';
import './mainFrontThree.css';
export const MainFrontThree = () => {
return (
<div >
<section className="main-front-section">
Hello world
</section>
</div>
)
}

You have two ways to fix this problem.
1. Set the mainFrontRandom to random component
const compDisplay = () => {
const randomDisplay = Math.floor(Math.random()*data.length);
setMainFrontRandom(randomDisplay)
}
)
}
2. Render the component from data and use index of mainFrontRandom
<>
<BrowserRouter>
<Navbar />
{/* <MainFrontOne/> */}
{/* <MainFrontTwo/> */}
{/* <MainFrontThree/> */}
{
data[mainFrontRandom] <--- this changed
}
<Routes>
<Route path="/" element={<Enterprice />}/>
<Route path="enterprice" element={<Enterprice />}/>
<Route path="developers" element={<Developers />}/>
<Route path="community" element={<Community />}/>
<Route path="download" element={<Download />}/>
<Route path="sign-up" element={<SignUp />}/>
<Route path="marketing" element={<Marketing />}/>
<Route path="consulting" element={<Consulting />}/>
</Routes>
</BrowserRouter>
</>
)
}

This example works fort me even when you reload. Look at the state, the component is there and not the number. Make sure you store the component in the state and not the index. Probably that is the issue with previous example.
import './App.css';
import { useEffect, useState } from 'react';
import MainFrontOne from './MainFrontOne';
import MainFrontTwo from './MainFrontTwo';
import MainFrontThree from './MainFrontThree';
function App() {
const data =[
<MainFrontOne/>, <MainFrontTwo/>, <MainFrontThree/>
]
const [mainFrontRandom, setMainFrontRandom] = useState(null);
const compDisplay = ()=>{
const randomDisplay = Math.floor(Math.random()*data.length);
setMainFrontRandom(data[randomDisplay])
}
useEffect(() => {
compDisplay()
}, [])
return (
<div className="App">
mainFrontRandom: {mainFrontRandom}
</div>
);
}
export default App;

Related

React v6-Redux Create PrivateRoutes

Im trying to create a PrivateRoutes in addition to the regular routes.
After login, the page is successfully re-direct to /home, however when I tried to open /work, the page will go back to /home. all the data from state.valid is also shows "unidentified" in /work.
I figured it out that inside the privateRoutes it check if valid.isAuthenticated is true or not. However since. valid.isAuthenticated is set to false as initial value in reducer, everytime I open /home or /work, it re-render /login and then render /home or /work.
How do I fix to not to render /login before opening other pages?
Here is my PrivateRoutes.js
import React from "react";
import { useSelector } from "react-redux";
import { Navigate } from "react-router-dom";
const PrivateRoute = ({ children }) => {
const valid = useSelector((state) => state.valid);
return valid.isAuthenticated ? children : <Navigate to="/login" />;
};
export default PrivateRoute;
here is my AppRouter.js
import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import PrivateRoute from "./PrivateRoute";
import App from "../components/App";
import Login from "../components/Login";
import HomePage from "../components/HomePage";
import WorkPage from "../components/WorkPage";
const AppRouter = () => (
<BrowserRouter>
<div>
<NavigationBar />
<div>
<Routes>
<Route path="/" element={<App />} exact />
<Route path="/login" element={<Login />} exact />
<Route path="/home" element={<PrivateRoute><HomePage /></PrivateRoute>} />
<Route path="/work" element={<PrivateRoute><WorkPage /></PrivateRoute>} />
</Routes>
</div>
</div>
</BrowserRouter>
);
export default AppRouter;
useEffect(() => {
if (valid.isAuthenticated) {
navigate("/home");
}
},[valid.isAuthenticated]);
import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import PrivateRoute from "./PrivateRoute";
import App from "../components/App";
import Login from "../components/Login";
import HomePage from "../components/HomePage";
import WorkPage from "../components/WorkPage";
const AppRouter = () => {
useEffect(() => {
if (!valid.isAuthenticated) {
navigate("/login");
}
});
return (
<BrowserRouter>
<div>
<NavigationBar />
<div>
{valid.isAuthenticated ? <>
<Routes>
<Route path="/" element={<App />} exact />
<Route path="/home" element={<HomePage />} />
<Route path="/work" element={<WorkPage />} />
</Routes>
</>
:
<>
<Routes>
<Route path="/login" element={<Login />} exact />
</Routes>
</>
}
</div>
</div>
</BrowserRouter>
)
};
export default AppRouter;

No routes matched location "/" react-router v6

I'm getting this message in the console, i tried to add the index property on the element but no render the element.
The problem is in the journalRoutes but i don't see the problem.
JournalRoutes.jsx:
import React from 'react'
import { Route, Routes } from 'react-router-dom'
import { JournalPage } from '../pages/JournalPage'
export const JournalRoutes = () => {
return (
<Routes>
<Route path="/" index element={<JournalPage/>}/>
<Route path='*' element={<JournalPage/>}/>
</Routes>
)
}
AppRouter.jsx:
import React from 'react'
import { Route, Routes } from 'react-router-dom'
import {AuthRoutes} from "../auth/routes/AuthRoutes"
import { JournalRoutes } from '../journal/routes/JournalRoutes'
export const AppRouter = () => {
return (
<Routes>
<Route path='/auth/*' element={<AuthRoutes/>}/>
<Route path='/journal' element={<JournalRoutes/>}/>
</Routes>
)
}
JournalApp.jsx:
import React from "react";
import { AppRouter } from "./router/AppRouter";
import { AppTheme } from "./theme/AppTheme";
export const JournalApp = () => {
return (
<AppTheme>
<AppRouter/>
</AppTheme>
);
};
Main.jsx:
import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import { JournalApp } from './JournalApp'
import { BrowserRouter} from "react-router-dom"
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<BrowserRouter>
<JournalApp />
</BrowserRouter>
</React.StrictMode>
)
The issue is in AppRouter rendering the root Routes component. It isn't rendering any "/" path. The "/" route path in JournalRoutes is built relative from the "/journal" route path of the Route rendering JournalRoutes.
You just need to render a route on "/" in App. It can render anything, including a redirect to "/journal" is that is what you consider to be the "home page".
Example:
import React from 'react';
import { Route, Routes, Navigate } from 'react-router-dom';
import { AuthRoutes } from "../auth/routes/AuthRoutes";
import { JournalRoutes } from '../journal/routes/JournalRoutes';
export const AppRouter = () => {
return (
<Routes>
<Route path='/auth/*' element={<AuthRoutes />} />
<Route path='/journal/*' element={<JournalRoutes />} />
<Route path="/" element={<Navigate to="/journal" />} /> // <-- path "/"
</Routes>
);
};
Additionally, while both path and index are optional props, you don't generally want to specify both at the same time. Remove one or the other.
Exmaple:
export const JournalRoutes = () => {
return (
<Routes>
<Route path="/" element={<JournalPage />} />
<Route path='*' element={<JournalPage />} />
</Routes>
);
};
or
export const JournalRoutes = () => {
return (
<Routes>
<Route index element={<JournalPage />} />
<Route path='*' element={<JournalPage />} />
</Routes>
);
};
i think you can git rid of the JournalRoutes and do this in your AppRouter instead
<Routes>
<Route path='/auth/*' element={<AuthRoutes/>}/>
<Route path='/journal'>
<Route index element={<JournalRoutes/>}/>
// this will route to /journal/sample but you should use Outlet to show nested routes in v6
<Route path='sample' element={<Sample/>}/>
<Route path='*' element={<NotFound/>}/>
</Route>
</Routes>
I think you could organise your routes something like this:
import React from 'react'
import { Route, Routes, Outlet } from 'react-router-dom'
import {AuthRoutes} from "../auth/routes/AuthRoutes"
import { JournalRoutes } from '../journal/routes/JournalRoutes'
export const AppRouter = () => {
return (
<Routes>
<Route path="/" element={<div>Add whatever you want at / route here</div>}/>
<Route path='/auth/*' element={<AuthRoutes/>}/>
<Route path='/journal' element={<Outlet/>}>
<Route index element={<JournalPage/>}/>
<Route path='*' element={<JournalPage/>}/>
</Route>
</Routes>
)
}

React Router Dom, protected route, getting ProtectedRoute is not a route

I created file auth.js file and ProtectedRoute.js in my application. Using JWT in API created a token and stored in local storage while login into my application. In my app.js imported the Authprovider and ProtectedRoute it shows error in route .please check my code and tell me where i made mistake
auth.js
import { useContext, createContext } from "react";
const AuthContext = createContext(null)
export const AuthProvider=({ children })=>{
const keyToken = localStorage.getItem("token");
const user = localStorage.getItem("name");
const userid = localStorage.getItem("id");
const pimg = localStorage.getItem("profile");
return(
<AuthContext.Provider value={{ keyToken,user,userid,pimg}}> {children}
</AuthContext.Provider>
)
}
export const useAuth = () => {
return useContext(AuthContext)
}
protectedRoute.js
import React from "react";
import { Navigate , Route } from "react-router-dom";
import {useAuth} from "./auth"
function ProtectedRoute({ component: Component, ...restOfProps }) {
const auth=useAuth();
const isAuthenticated = auth.keyToken;
console.log("this", isAuthenticated);
return (
<Route
{...restOfProps}
render={(props) =>
false ? <Component {...props} /> : <Navigate to="/login" />
}
/>
);
}
export default ProtectedRoute;
App.js
import React from "react";
import ReactDOM from "react-dom";
import {BrowserRouter as Router,Routes,Route} from 'react-router-dom';
import Login from "./components/SignIn";
import Category from "./pages/Category";
import Addcategory from "./pages/Addcategory";
import Subcategory from "./pages/Subcategory";
import Dashboard from "./pages/Dashboard";
import { Profile } from "./components/Profile";
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { AuthProvider} from "./components/authentication/auth";
import ProtectedRoute from "./components/authentication/protectedRoute";
function App() {
return (
<AuthProvider>
<Router>
<Routes>
<Route exact path='/' element={< Login />}></Route>
<Route exact path='/login' element={< Login />}></Route>
<ProtectedRoute exact path='/dashboard' element={ Dashboard}/>
{/*<Route exact path='/dashboard' element={< Dashboard />}></Route>*/}
<Route exact path='/category' element={< Category />}></Route>
<Route exact path='/categoryAdd' element={< Addcategory />}></Route>
<Route exact path='/subcategory' element={< Subcategory />}></Route>
<Route exact path='/profile' element={< Profile />}></Route>
</Routes>
<ToastContainer />
</Router>
</AuthProvider>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
export default App;
Error showing in console:
While what you did for ProtectedRoute I think would work for React Router Dom version 5, the version 6 is slightly different. Here is one way to do it (look at this example made by the library team to know more):
App.js:
function App() {
return (
<AuthProvider>
<Router>
<Routes>
<Route exact path='/dashboard' element={ <ProtectedRoute/>}/>
</Routes>
<ToastContainer />
</Router>
</AuthProvider>
);
}
ProtectedRoute.js:
function ProtectedRoute() {
const auth=useAuth();
const isAuthenticated = auth.keyToken;
if(isAuthenticated){
return <Dashboard/>
}
return (
<Navigate to="/login" />
);
}
export default ProtectedRoute;
You have mixed code of react-router-dom v5 and v6 you can read the migrate guide upgrading from v5
Can using Outlet to render ProtectedRoute as layout. Check this example
// ProtectedRoute.js
import { Navigate, Outlet } from 'react-router-dom';
export const ProtectedRoute = () => {
const location = useLocation();
const auth = useAuth();
return auth.isAuthenticated
? <Outlet />
: <Navigate to="/login" state={{ from: location }} replace />;
};
// App.js
import { BrowserRouter, Routes, Route } from "react-router-dom";
function App() {
return (
<AuthProvider>
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/" element={<ProtectedRoute /> }>
<Route path='dashboard' element={<Dashboard />} />
<Route path='category' element={<Category />} />
// rest of your code
</Route>
</Routes>
<ToastContainer />
</BrowserRouter>
</AuthProvider>
);
}

Parameters Routing

I'm having a problem in getting the output of the "match" object value in this parameter routing code.
This is class where I use match:
import React from "react";
const ProductDetails = (props) => {
console.log(props.match);
return <h1>Details No. </h1>;
};
export default ProductDetails;
And the code I use for using the route is:
import React, { Component } from "react";
import NavBar from "./navbar";
import ProductDetails from "./productDetails";
class App extends Component {
render() {
return (
<React.Fragment>
<NavBar
productsCount={this.state.Product.filter((p) => p.count > 0).length}
/>
<main className="container">
<Routes>
<Route path="/about" element={<About />} />
<Route path="/" element={<Home />} />
<Route path="/contact" element={<Contact />} />
<Route
path="/cart"
element={
<ShoppingCart
products={this.state.Product}
onReset={this.resetData}
onIncrement={this.incrementEntry}
onDelete={this.deleteEntery}
/>
}
/>
<Route path="/products/:id" element={<ProductDetails />} />
</Routes>
</main>
</React.Fragment>
);
}
}
And I get the answer as "undefined" and a lot of red errors msgs.
if you are using react router v6 and what you want to do is getting the id, it would be:
import React from "react";
const ProductDetails = () => {
const {id} = useParams();
return <h1>Details No. {id}</h1>;
};
export default ProductDetails;
or if you really want the match object:
import React from "react";
const ProductDetails = () => {
const match = useMatch();
return <h1>Details No.</h1>;
};
export default ProductDetails;
What is element? If you use react-router-dom for routing you must set the component for any route.
<BrowserRouter>
<Route path ="/about" component= {<About />} />
<Route path ="/" component= {<Home/>}/>
<Route path ="/contact" component= {<Contact/>}/>
<Route path ="/cart" component= {<ShoppingCart
products= {this.state.Product}
onReset ={this.resetData}
onIncrement ={this.incrementEntry}
onDelete = {this.deleteEntery}/>}/>
<Route path="/products/:id" component={<ProductDetails />}/>
</BrowserRouter>

React router rendering two child components instead of just one

I'm trying to add routes to my application but for some reason there are two components being rendered to the page instead of just one.
My code looks like this (the relevant part):
import React from "react";
import Board from "./Components/Board";
import Navbar from "./Components/Navbar";
import TaskDetail from "./Components/TaskDetail";
import { LanesProvider } from "./Context/lanes.context";
import { TasksProvider } from "./Context/tasks.context";
import { BrowserRouter, Route, Switch } from "react-router-dom";
function App(props) {
const getTask = props => {
return <TaskDetail />;
};
return (
<>
<LanesProvider>
<TasksProvider>
<Navbar />
<Board />
<BrowserRouter>
<Switch>
<Route exact path="/" render={() => <Board />} />
<Route exact path="/board" render={() => <Board />} />
<Route exact path="/board/:taskName" render={() => getTask()} />
</Switch>
</BrowserRouter>
</TasksProvider>
</LanesProvider>
</>
);
}
Now basically when I'm navigating to "localhost/board/test" I would expect to just see the <TaskDetail/> component but instead I get the <Board /> AND <TaskDetail/>.
I didn't expect this to happen because of the exact boolean.
FYI: getTask() is only returning a component right now because I wanted to get the routes to work first before implementing further logic.
So far I could not find a solution to this.
Thank you in advance.
There is a <Board /> component outside your <BrowserRouter>
import React from "react";
import Board from "./Components/Board";
import Navbar from "./Components/Navbar";
import TaskDetail from "./Components/TaskDetail";
import { LanesProvider } from "./Context/lanes.context";
import { TasksProvider } from "./Context/tasks.context";
import { BrowserRouter, Route, Switch } from "react-router-dom";
function App(props) {
const getTask = props => {
return <TaskDetail />;
};
return (
<>
<LanesProvider>
<TasksProvider>
<Navbar />
<Board /> --> Remove this component from here
<BrowserRouter>
<Switch>
<Route exact path="/" render={() => <Board />} />
<Route exact path="/board" render={() => <Board />} />
<Route exact path="/board/:taskName" render={() => getTask()} />
</Switch>
</BrowserRouter>
</TasksProvider>
</LanesProvider>
</>
);
}

Categories

Resources