Reputation: 633
I have a basic texting app I want to make and am following a tutorial on react and meteor but the only problem is that the tutorial is using react-router v3 and I want to get used to react-router v4. How would I make the equivalent of doing something like:
browserHistory.replace("/chat");
I also am doing it outside of a component so I cannot do:
this.props.history.push("/chat");
I am trying to run a function every time someone is entering a page, which checks if the user is authenticated or not and what page they are on. Here is my code so far:
Main.js
import React from "react";
import ReactDOM from "react-dom";
import {Meteor} from "meteor/meteor";
import {Tracker} from "meteor/tracker";
import { BrowserRouter, Route, Switch, Redirect, withRouter} from 'react-router-dom'
import {Texts} from "./../imports/api/Text";
import App from "./../imports/ui/App";
import Name from "./../imports/ui/Name";
import NotFound from "./../imports/ui/NotFound";
import Signup from "./../imports/ui/Signup";
import Login from "./../imports/ui/Login";
Meteor.startup(() => {
Tracker.autorun(() => {
let texts = Texts.find().fetch();
let signedIn = !!Meteor.userId();
let onPrivatePage = ["/chat"];
let onPublicPage = ["/signup", "/login"];
const isUserAuthenticated = withRouter(({history}) => {
if(signedIn && onPublicPage){
console.log("Signed In")
}
if(!signedIn && onPrivatePage){
console.log("Signed Out")
}
});
const routes = (
<BrowserRouter>
<Switch>
<App path="/chat" texts={texts} render={isUserAuthenticated()}/>
<Signup path="/signup" render={isUserAuthenticated()}/>
<Login path="/login" render={isUserAuthenticated()}/>
<Route component={NotFound}/>
</Switch>
</BrowserRouter>
);
ReactDOM.render(routes, document.getElementById("app"));
});
});
Signup.js
import React from "react"
import {withRouter} from "react-router-dom";
import {Accounts} from "meteor/accounts-base"
import {Link} from "react-router-dom";
class Signup extends React.Component{
constructor(props){
super(props);
this.state = {
error: ""
}
}
SignupUser(e){
e.preventDefault();
let username = this.refs.username.value;
let password = this.refs.password.value;
User = {
username,
password
};
Accounts.createUser(User, (err) => {
if(err){
this.setState({
error:err.reason
})
}else{
console.log("success")
}
});
}
render(){
return(
<div>
<form onSubmit={this.SignupUser.bind(this)}>
<h1>Register Here</h1>
{this.state.error}
<br />
<input type="username" ref="username" />
<input type="password" ref="password" />
<button>Signup</button>
<br />
<Link to="/login">I already have an account.</Link>
</form>
</div>
)
}
}
export default withRouter(Signup);
Login.js
import React from "react";
import {withRouter} from "react-router-dom";
import {Meteor} from "meteor/meteor";
import {Link} from "react-router-dom";
class Login extends React.Component{
constructor(props){
super(props)
this.state = {
error:""
}
}
loginUser(e){
e.preventDefault()
let username = this.refs.username.value.trim();
let password = this.refs.password.value.trim();
Meteor.loginWithPassword({username}, password, (err)=>{
if(err){
this.setState({
error: err.reason
})
}else{
console.log("Logged in")
}
});
}
render(){
return(
<div>
<form onSubmit={this.loginUser.bind(this)}>
<h1>Login</h1>
{this.state.error}
<br />
<input ref="username" type="text" placeholder="Username" />
<input ref="password" type="password" placeholder="Password" />
<button>Login</button>
<br />
<Link to="/signup">Need an account?</Link>
</form>
</div>
)
}
}
export default withRouter(Login);
Upvotes: 2
Views: 4592
Reputation: 7777
There is another way to do this that is more React Router v4 friendly, and is actually a lot less fuss, and involves using the Redirect
component
Import the component like this:
import { Link, Redirect } from 'react-router-dom';
In your render method do something like this:
if (!Meteor.userId())
return <Redirect to={"/login"} />
Or if you want to push it onto the history add the push
property
if (!Meteor.userId())
return <Redirect to={"/login"} push />
Upvotes: 0
Reputation: 1692
Change your isUserAuthenticated
code to the following:
const isUserAuthenticated = withRouter(({history}) => {
if(signedIn && onPublicPage){
console.log("Signed In")
}
if(!signedIn && onPrivatePage){
console.log("Signed Out")
}
});
So you will be able to do the history.push('/some-route/') when needed. Just don't forget to add withRouter
in your import from react-router-dom
, like this:
import { BrowserRouter, Route, Switch, Redirect, withRouter } from 'react-router-dom'
As for the auth flow, checkout this auth example from React Router 4 docs. It will definitely help you!
Upvotes: 3