最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Redirecting using React Router shows blank page - Stack Overflow

programmeradmin2浏览0评论

I'm trying to build a simple example project where the user is redirected to the 'contact' page upon clicking a button, using React. I'm trying to achieve this by setting the value of a state property. When I run the code I have, it does change the browser address bar URL to that of the contact page, but does not seem to actually load the ponent - I get a blank page instead. If I manually navigate to that URL (http://localhost:3000/contact) I can see the contents.

Here are my App.js and Contact.js files -

App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route, Link, Redirect } from 'react-router-dom';
import Contact from './Contact';

class App extends Component {
    state = {
        redirect: false
    }

    setRedirect = () => {
        this.setState({
            redirect: true
        })
    }

    renderRedirect = () => {
        if (this.state.redirect) {
            return <Redirect to='/contact' />
        }
    }

    render() {
        return (
            <Router>
                <Switch>
                    <Route exact path='/contact' ponent={Contact} />
                </Switch>
                <div>
                    {this.renderRedirect()}
                    <button onClick={this.setRedirect}>Redirect</button>
                </div>
            </Router>
        )
    }
}

export default App;

Contact.js

import React, { Component } from 'react';

class Contact extends Component {
    render() {
        return (
            <div>
                <h2>Contact Me</h2>
                <input type="text"></input>
            </div>
        );
    }
}

export default Contact;

Using state isn't really a requirement for me, so other (preferably simpler) methods of redirection would be appreciated too.

I'm trying to build a simple example project where the user is redirected to the 'contact' page upon clicking a button, using React. I'm trying to achieve this by setting the value of a state property. When I run the code I have, it does change the browser address bar URL to that of the contact page, but does not seem to actually load the ponent - I get a blank page instead. If I manually navigate to that URL (http://localhost:3000/contact) I can see the contents.

Here are my App.js and Contact.js files -

App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route, Link, Redirect } from 'react-router-dom';
import Contact from './Contact';

class App extends Component {
    state = {
        redirect: false
    }

    setRedirect = () => {
        this.setState({
            redirect: true
        })
    }

    renderRedirect = () => {
        if (this.state.redirect) {
            return <Redirect to='/contact' />
        }
    }

    render() {
        return (
            <Router>
                <Switch>
                    <Route exact path='/contact' ponent={Contact} />
                </Switch>
                <div>
                    {this.renderRedirect()}
                    <button onClick={this.setRedirect}>Redirect</button>
                </div>
            </Router>
        )
    }
}

export default App;

Contact.js

import React, { Component } from 'react';

class Contact extends Component {
    render() {
        return (
            <div>
                <h2>Contact Me</h2>
                <input type="text"></input>
            </div>
        );
    }
}

export default Contact;

Using state isn't really a requirement for me, so other (preferably simpler) methods of redirection would be appreciated too.

Share Improve this question asked Jun 7, 2019 at 19:29 Debadeep SenDebadeep Sen 4651 gold badge9 silver badges21 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

Since your button is nothing more than a link, you could replace it with:

<Link to="/contact">Redirect</Link>

There are many alternatives though, you could for example look into BrowserRouter's browserHistory:

import { browserHistory } from 'react-router'

browserHistory.push("/contact")

Or perhaps this.props.history.push("/contact").

There are pros and cons to every method, you'll have to look into each and see which you prefer.

I got here for a similiar situation. It's possible use withRouter (https://reactrouter./web/api/withRouter) to handle that.

This example was tested with "react": "^16.13.1","react-router-dom": "^5.2.0" and "history": "^5.0.0" into "dependecies" sections in package.json file.

In App.js I have the BrowserRouter (usually people import BrowserRouter as Router, I prefer work with original names) with Home and Contact.

App.js

import React, { Component } from "react";
import {
    BrowserRouter,
    Switch,
    Route,
} from "react-router-dom";
import Home from "./pages/Home";
import Contact from "./pages/Contact";
class App extends Component
{
    // stuff...
    render()
    {
        return (
            <BrowserRouter>
                <Switch>
                    <Route path="/contact">
                        <Contact />
                    </Route>
                    <Route path="/">
                        <Home />
                    </Route>
                </Switch>
            </BrowserRouter>
        );
    }
}
export default App;

ASIDE 1: The Route with path="/contact" is placed before path="/" because Switch render the first match, so put Home at the end. If you have path="/something" and path="/something/:id" place the more specific route (with /:id in this case) before. (https://reactrouter./web/api/Switch)

ASIDE 2: I'm using class ponent but I believe (I didn't test it) a functional ponent will also work.

In Home.js and Contact.js I use withRouter associated with export keyword. This makes Home and Contact ponents receive the history object of BrowserRouter via props. Use method push() to add "/contact" and "/" to the history stack. (https://reactrouter./web/api/history).

Home.js

import React from "react";
import {
    withRouter
} from "react-router-dom";

export const Home = ( props ) =>
{
    return (
        <div>
            Home!
            <button
                onClick={ () => props.history.push( "/contact" ) }
            >
                Get in Touch
            <button>
        </div>
    );
}
export default withRouter( Home );

Contact.js

import React from "react";
import {
    withRouter
} from "react-router-dom";

export const Contact = ( props ) =>
{
    return (
        <div>
            Contact!
            <button
                onClick={ () => props.history.push( "/" ) }
            >
                Go Home
            <button>
        </div>
    );
}
export default withRouter( Contact );

Particularly, I'm using also in a BackButton ponent with goBack() to navigate backwards:

BackButton.js

import React from "react";
import {
    withRouter
} from "react-router-dom";

export const BackButton = ( props ) =>
{
    return (
        <button
            onClick={ () => props.history.goBack() }
        >
            Go back
        <button>
    );
}
export default withRouter( BackButton );

So I could modify the Contact to:

Contact.js (with BackButton)

import React from "react";
import BackButton from "../ponents/BackButton";

export const Contact = ( props ) =>
{
    return (
        <div>
            Contact!
            <BackButton />
        </div>
    );
}
export default Contact; // now I'm not using history in this file.
// the navigation responsability is inside BackButton ponent.

Above was the best solution for me. Other possible solutions are:

  • useHistory Hook (https://reactrouter./web/api/Hooks)
  • work with Router instead BrowserRouter - (https://reactrouter./web/api/Router)
发布评论

评论列表(0)

  1. 暂无评论