将路由器v4重定向到组件外的另一个页面

时间:2017-08-14 20:20:17

标签: reactjs meteor react-router react-router-v4

我有一个基本的发短信应用程序我想制作并遵循反应和流星的教程,但唯一的问题是该教程使用react-router v3,我想习惯反应路由器v4。我将如何做出类似的事情:

browserHistory.replace("/chat");

我也是在组件之外做的,所以我不能这样做:

this.props.history.push("/chat");

我试图在每次有人进入页面时运行一个函数,该页面检查用户是否经过身份验证以及他们所在的页面。到目前为止,这是我的代码:

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);

2 个答案:

答案 0 :(得分:3)

将您的isUserAuthenticated代码更改为以下内容:

const isUserAuthenticated = withRouter(({history}) => {
    if(signedIn && onPublicPage){
        console.log("Signed In")
    }
    if(!signedIn && onPrivatePage){
        console.log("Signed Out")
    }
});

因此,您可以在需要时执行history.push(&#39; / some-route /&#39;)。不要忘记在withRouter的导入中添加react-router-dom,如下所示:

import { BrowserRouter, Route, Switch, Redirect, withRouter } from 'react-router-dom'

至于身份验证流程,结帐this auth example from React Router 4 docs。它一定会帮到你!

答案 1 :(得分:0)

有另一种方法可以做到这一点,React Router v4更友好,实际上不那么大惊小怪,并涉及使用Redirect组件

像这样导入组件:

import { Link, Redirect } from 'react-router-dom';

在你的渲染方法中做类似的事情:

if (!Meteor.userId())
  return <Redirect to={"/login"} />

或者,如果您想将其推送到历史记录中,请添加push属性

if (!Meteor.userId())
  return <Redirect to={"/login"} push />