Basic way to handle login with React - javascript

I'm working on a client-side app using create-react-app. The application renders a login component with a basic form and I want to load another component (which will be the main application) on successful login.
The validation and the login logic is not the issue at the moment because first I'm trying to figure out a simple way to dismount the login component and load another component on the submit event.
class Login extends Component {
handleLogin(){
// trigger to load Main.js
}
render() {
return (
// form elements here
<div className="submit">
<input className="button-signin" value="Sign In" type="submit"
onClick={this.handleLogin}/>
</div>
);
}
}
What would be the easiest way to switch to another component (which I called Main.js in this example) on submit event?

Have you tried using React router? It makes really easy to define routes and assign a Component to each of them. Then you can also establish conditions for accessing each route. There is an example in the official docs that seems to match your requirements.
<Router history={withExampleBasename(browserHistory, __dirname)}>
<Route path="/" component={App}>
<Route path="login" component={Login} />
<Route path="logout" component={Logout} />
<Route path="about" component={About} />
<Route path="dashboard" component={Dashboard} onEnter={requireAuth} />
</Route>
The method requireAuth will be checked each time you try to access the route dashboard (which will show the component Dashboard). If you are using token-based authentication, you might have a token stored in the localStorage and check if it's present in requireAuth.
Your method handleLogin would call the backend, log the user in (store the token in localStorage if that's how the login is handled) and then redirect to the dashboard route.

Related

Github pages HashRouter not displaying components

My react app on github page doesn't render the components using HashRouter, blank page on "/" and 404 error on "/about".
this is my app.js
function App() {
return (
<div className="Container-fluid" id="div2">
<HashRouter basename="/Landing-Page">
<Header />
<Routes>
<Route path="/thankyou" element={<ThankYou />} />
<Route
exact
path="/"
element={
<div className="Container">
<SignUp validate={validate} />
<EbookInfo />
</div>
}
/>
<Route path="/about" element={<About />} />
</Routes>
</HashRouter>
</div>
);
}
on homepage it shows .../Landing-Page/ as expected
but on other page it shows .../about instead of .../Landing-Page/about.
I have gh-pages setup.
my github page https://alexhmar.github.io/Landing-Page/
my repo https://github.com/alexhmar/Landing-Page/tree/master
I have also tried this with <Router basename={process.env.PUBLIC_URL} but it's the same issue.
When using Github Pages and React Router Dom you need to use the Hash Router.
Replace your import by import { HashRouter as Router } from "react-router-dom"; and it should work.
Github Pages isn't configured for single page applications, if you try to access /bar, it will try to find a bar.html file and thus give you a 404. By using the hash router, when you navigate to links it will go to /#bar so Github Pages won't redirect you and React Router Dom will see it as navigating to /bar as you'd expect it, as long as you're using the Link component or the hooks.
I deployed on Heroku instead of Github pages,now it's working fine.

How do I create a multiple page app with a login component in react?

Recently I've tried building a web platform trough React. Everything's fine, everything's work ecc.
But I've run in many problems when I tried to create a different page for the user login:
I already had Routes in my code, so when I tried to add other Routes to another js file they simply didn't work.
I have no clue how to do the authentication in react router, I've tried in many ways, followed many tutorials but nothing worked out.
<Switch>
<Route exact path='/' component={Feed}/>
<Route path="/user" component={Profilo}/>
<Route path='/explore-page' component={ExplorePage} />
<Route path='/events-page' component={EventsPage} />
<Route path='/calendar-page' component={CalendarPage} />
<Route path='/stats-page' component={StatsPage} />
<Route path='/form' component={FormPage}/>
<Route path="/user" component={Profilo}/>
<Route path="/user/:userId" component={Profilo} />
</Switch>
This is all the routes I'm currently using inside a div to get the react component rendered.
As I said before adding other routes in an upper file wouldn't give me a response.
So, in the end, I'm gonna ask you where should I put the route for the login and the home? In there or I should just moving everything?
Thank you in advance.
One simple way is adding the logic to handle authentication in your render function.
If the user is not authenticated. Redirect to the login page. Otherwise, go to your component
render() {
if (!this.props.isAuth) {
return (
<Switch>
<Route exact path="/" component={Login} />
<Redirect to="/" />
</Switch>
);
}
return (<Switch>
<Route
// your router
/>
</Switch>);
}

React Router | load component only on page refresh

I'm using React Router v4 Browser Router. My scenario is I have call login page on every page refresh (Browser Refresh click or F5)
Route
<Router history={history}>
<div>
<Spin spinning={this.props.isloading}>
<Switch>
<Route path="/login" component={Login} />
<Route path="/Dashboard" component={Dashboard} />
<Route path='*' component={NotFound} />
</Switch>
</Spin>
</div>
</Router>
I need to load login component on page refresh so I need something like below
<Refresh path="/login" component={Login} />
It happens to me and the issue was i am importing Router from react-router-dom instead of BrowserRouter as Router.
Create a componentDidMount method in your root component, which will be responsible for logging in your user by redirecting the user to /login.
Then add a event listener for page refresh which will logout the user for any page refresh.
componentDidMount(){
if(!userLoggedIn()){
//redirect to login
history.push("/login")
}
window.addEventListener('beforeunload', logoutTheUser);
/* if you are not maintaining a session, you dont need this
as user will be logged out automatically on page refresh.*/
}
Just do something like:
const Refresh = ({reload, children}) => reload ? children : null;
...
<Refresh reload={performance.navigation.type === 1}>
<Redirect to="/login"/>
</Refresh>
Based on:
Check if page gets reloaded or refreshed in Javascript
https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigation

React BrowserRouter - how to programmatically navigate to different routes?

I currently have this in my app.js file:
<BrowserRouter>
<div>
<Switch>
<Route exact path="/" component={CompOne}/>
<Route path="/two" component={CompTwo} />
</Switch>
</div>
</BrowserRouter>
In my CompOne, I want to programmatically navigate to CompTwo. I know I can use window.location to navigate to the /two path, but I would like to pass in some props to CompTwo.
How would I go about programmatically navigating from CompOne to CompTwo while passing in props?
One of the ways to do it is to make use of history.push() property so if you want to navigate to CompTwo you can do something like this inside CompOne :
this.props.history.push('/CompTwo');

Multiple ReactDOM.render calls with shared router context

I got two React components rendered like this.
ReactDOM.render(
<Router history={ browserHistory }>
<Route path='/items' component={ App }>
<IndexRoute component={ Home } />
<Route path='/items/:id' component={ Details } />
</Route>
</Router>,
document.getElementById('app')
);
And the second one, which is a sidebar.
ReactDOM.render(
<Sidebar />,
document.getElementById('sidebar')
);
I'd like to use the Link helper from react-router in the Sidebar component. However, I get the following error: "Uncaught Invariant Violation: Links rendered outside of a router context cannot navigate.". Which makes sense, because the sidebar is not within the router context like the first seen above.
Is there a way to share the router context with the sidebar?
I'd like to change the sidebar layout based on the route (and access the router object in this.props properly) and use Link as it should be.
I don't want to work my way around hacky approaches like history.pushState, or parsing location.path to change the sidebar's layout according to the corresponding route of items.
You should be able to just render your sidebar in its own <Router>. The important thing is that they share the same history instance (in this case, browserHistory).
When a <Router> mounts, it adds a listener to its history instance. When a history instance receives a new location, it notifies all of its listeners.
ReactDOM.render((
<Router history={browserHistory}>
<Route component={Sidebar} />
</Router>
) document.getElementById('sidebar')

Categories

Resources