this is my code , I am try to render my screens container div base on token saved in localStorage, I use useState to save my token but when you logOut or logIn you need to refresh, I do not know how to useEffect here to re-render base on localStorage.
I want to whenever user logged in or logged out my app component get rendered .
function App() {
const [isloggedIn, setIsLoggedIn] = useState(localStorage.getItem("token"));
return (
<BrowserRouter>
<Routes>
<Route
path="/login"
element={<Login />}
/>
</Routes>
{isloggedIn && <div className="screens-container">
<Sidebar />}
<div className="screens-section-container">
<Navbar />
<Routes>
<Route element={<PrivateRoutes />}>
<Route
element={<Home />}
path="/"
exact
/>
</Route>
</Routes>
</div>
</div>}
</BrowserRouter>
);
}
Related
function App() {
return (
<RecoilRoot>
<Router>
<Navbar />
<Routes>
<Route path={"/"} element={<Home />} />
<Route path={`/page/:menu`} element={<MovieMenu />} />
<Route path={`/movie/:id`} element={<Detail />} />
<Route path={`/search/:searchText`} element={<Search />} />
<Route path={"*"} element={<NotFound />} />
</Routes>
</Router>
</RecoilRoot>
);
}
If i process 404 page in the above way, / handle it well, but <NotFound /> not be rendered if any path is entered after /page/fldlfsd;lf; or /search/dsklfskldf. Is there a way?
Paths like "/page/fldlfsd;lf;" and "/search/dsklfskldf" will be matched and rendered by the Routes component. The route param validation needs to occur in the routed component.
Each component can use the useParams hook to access the route param, validate it, and redirect to the NotFound route if param is invalid.
To help with this I suggest creating a discrete route to render NotFound so you can imperatively redirect to it from components and create a redirect route to handle unknown routes.
Example:
function App() {
return (
<RecoilRoot>
<Router>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/page/:menu" element={<MovieMenu />} />
<Route path="/movie/:id" element={<Detail />} />
<Route path="/search/:searchText" element={<Search />} />
<Route path="/404" element={<NotFound />} />
<Route path="*" element={<Navigate to="/404" replace />} />
</Routes>
</Router>
</RecoilRoot>
);
}
...
MovieMenu
const navigate = useNavigate();
const { menu } = useParams();
useEffect(() => {
... logic to validate menu param ...
if (invalidMenu) {
navigate("/404", { replace: true });
}
}, [menu, navigate]);
...
I want to put a div inside <Routes> and also Render a <Topbar /> and <Sidebar /> component inside <Routes> without <Route> tag for them.
My code is as follows:-
const App = () => {
return (
<Router>
<Routes>
<Route path="login" element={<Login />} />
<Topbar />
<div className="container">
<Sidebar />
<Route path="/" element={<Home />} />
<Route path="users" element={<UserList />} />
</div>
</Routes>
</Router>
);
};
I want to implement <Topbar /> and <Sidebar /> for all the routes.
But for an exception of login Page (Topbar and Sidebar should not be shown on the login page).
That's why I had put login Route at the top of Topbar and Sidebar.
The console is showing error as:
Uncaught Error: [Topbar] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
How to implement this functionality?
In react-router-dom v6 only Route and React.Fragment components are valid children for the Routes component.
Use layout components to render the Topbar and Sidebar components along with an Outlet for nested routes for the routes you want to render these components.
Example:
import { Routes, Route, Outlet } from 'react-router-dom';
const Layout = () => (
<>
<Topbar />
<div className="container">
<Sidebar />
<Outlet />
</div>
</>
);
const App = () => {
return (
<Router>
<Routes>
<Route path="/login" element={<Login />} />
<Route element={<Layout />}>
<Route path="/" element={<Home />} />
<Route path="users" element={<UserList />} />
</Route>
</Routes>
</Router>
);
};
Change your routes like below,
you need to check whether user is logged in or not, if user logged in use Tobbar, Sidebar etc, otherwise just return login route
const App = () => {
const [isLogin, setIsLogin] = useState(false)
return (
<Router>
<Routes>
{ isLogin ? <Topbar />
<div className="container">
<Sidebar />
<Route path="/" element={<Home />} />
<Route path="users" element={<UserList />} />
</div> : <Route path="login" element={<Login />} />
</Routes>
</Router>
);
};
These are my public routes
export const PublicRoutes = () => {
return (
<Switch>
<Route path="/" exact component={Login} />
<Route path={constant.component.logout.url} exact={true} component={Logout} />
<Route path={constant.component.register.url} exact= {true} component={SignUp} />
<Route path={constant.component.forgotPassword.url} exact={true} component={ForgotPassword} />
</Switch>
)
}
This is my index.js
ReactDOM.render(
<React.StrictMode>
<AlertProvider template={AlertTemplate} {...options}>
<Router>
<App />
</Router>
</AlertProvider>
</React.StrictMode>,
document.getElementById('root')
);
This is my app.js where I am trying to render routes based on accessToken in the local storage
return (
<>
{token ? <DashboardLayout /> : <PublicRoutes />}
</>
)
And finally this my dashboard layout where I want the authenticated routes to be shown to the right of the sidebar
<>
<SideBar>
<div className="w-100">
<Switch>
<Route path="/dashboard" component={Dashboard} />
<Route path="/my-account" component={Account} />
</Switch>
</div>
<Footer>
</>
Now, when I login, it redirects me to "/dashboard" the url changes but the page shows an empty screen and it works if I refresh the page manually. What am I doing wrong? Thanks
Are you sure your token is not empty right after you login ? Maybe your token is empty at this moment, PublicRoutes is rendered and that's why the /dashboard route display an empty screen. Maybe your token only gets value after refresh.
I am trying to read data from a Firebase real-time database and pass the object to a component in React as its state so that the component can automatically render when any changes are made to the database. The data that I retrieve is stored in the variable local_data and it is to be passed to the Full component.
However the page just constantly keeps refreshing when implemented this way. Instead I would like it to just show real time updates if any changes were made to the database.
The following are the relevant snippets of code (in Full.js this.state is passed to Charts):
index.js
var local_data = {}
window.location.reload();
ReactDOM.render((
<div>
<HashRouter>
<Switch>
<Route exact path="/login" name="Login Page" component={Login}/>
<Route exact path="/register" name="Register Page" component={Register}/>
<Route exact path="/404" name="Page 404" component={Page404}/>
<Route exact path="/500" name="Page 500" component={Page500}/>
<Route path="/original" name="Home" component={Full} sample={local_data}/>
<Route path="/" name="Home" render={props => <Full local_data= {local_data} />} />
</Switch>
</HashRouter>
</div>
), document.getElementById('root'));
Full.js
class Full extends Component {
constructor(props) {
super(props);
//Change this to be an object to iterate.
console.log("In Full.js ->",props.local_data.greeting);
this.state = {};
}
componentWillMount(){
/* Create reference to messages in Firebase Database */
let db = firebase.database().ref('/');
db.off();
db.on('value', snapshot => {
/* Update React state when message is added at Firebase Database */
let locData = snapshot.val();
//this.setState(locData);
this.state = locData;
})
}
render() {
return (
<div className="app">
<Header />
<div className="app-body">
<Sidebar {...this.props}/>
<main className="main">
<Breadcrumb />
<Container fluid>
<Switch>
<Route path="/dashboard" name="Dashboard" component={Dashboard}/>
<Route path="/components/buttons" name="Buttons" component={Buttons}/>
<Route path="/components/cards" name="Cards" component={Cards}/>
<Route path="/components/forms" name="Forms" component={Forms}/>
<Route path="/components/modals" name="Modals" component={Modals}/>
<Route path="/components/social-buttons" name="Social Buttons" component={SocialButtons}/>
<Route path="/components/switches" name="Swithces" component={Switches}/>
<Route path="/components/tables" name="Tables" component={Tables}/>
<Route path="/components/tabs" name="Tabs" component={Tabs}/>
<Route path="/icons/font-awesome" name="Font Awesome" component={FontAwesome}/>
<Route path="/icons/simple-line-icons" name="Simple Line Icons" component={SimpleLineIcons}/>
<Route path="/widgets" name="Widgets" component={Widgets}/>
<Route path="/charts_original" name="Charts" component={Charts} />
<Route path="/charts" name="Charts" render={props => <Charts local_data={this.state} {...props} />} />
<Redirect from="/" to="/dashboard"/>
</Switch>
</Container>
</main>
<Aside />
</div>
<Footer />
</div>
);
}
}
export default Full;
Use db.on('value', snap => this.setState(snap.val())) in your Full.js's componentDidMount. React doesn't like you mutating state directly https://reactjs.org/docs/react-component.html#state
I have a repo to reproduce this and see the error: https://github.com/rublev/parcel-static1/tree/master
The basic structure of my routes is as follows:
// app/app.js
const render = Component => {
ReactDOM.render(
<AppContainer>
<Provider store={ store }>
<ConnectedRouter history={ history }>
<Route component={ Component } />
</ConnectedRouter>
</Provider>
</AppContainer>,
document.getElementById('react-root')
)
}
// app/containers/App/index.js
<div className='app'>
<Switch location={ location }>
<Route exact path='/' render={() => (
loggedIn ? (
<Redirect to='/organizations' push />
) : (
<Redirect to='/onboarding' push />
)
)}/>
<Route path='/organizations' component={ Organizations } />
<Route path='/onboarding' component={ Onboarding } />
<Route path='/settings' component={ Settings } />
</Switch>
</div>
// app/flows/onboarding/Onboarding/index.js
<div>
<Route exact path={`${match.url}`} component={ Start }/>
<Route path={`${match.url}/signup`} component={ SignUp }/>
<Route path={`${match.url}/name`} component={ Name }/>
<Route path={`${match.url}/structure`} component={ Structure }/>
<Route path={`${match.url}/pricing`} component={ Pricing }/>
<Route path={`${match.url}/continue`} component={ Continue }/>
</div>
// app/flows/onboarding/Start/index.js
<div className='start'>
Start Page
</div>
I'm not sure where the error could be coming from or how to do this different.
I have three main routes:
/onboarding
/organizations
/settings
I'd like to redirect to either /onboarding or /settings depending on login state. Once at either of these main routes, there will be sub routes.
What is the proper way to set these routes up with a redirect without causing a redirect error?
error on launching localhost:8080/:
In your render function, change
<Route component={ Component } />
to
<Component />
Also, you shouldn't need to pass location as a prop into the Switch in App.