<Redirect />的正确使用方法

3

在阅读教程之后,我成功弄清了<Redirect />的用法,代码如下:

import React from 'react';
import Login from './Login';
import Dashboard from './Dashboard';
import {Route, NavLink, BrowserRouter, Redirect} from 'react-router-dom';

const supportsHistory = 'pushState' in window.history;

export default class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            username: '',
            password: '',
            redirectToDashboard: false,
        }
    }

//-----------------------LOGIN METHODS-----------------------------
    onChangeInput(e) {
        this.setState({[e.target.name]:e.target.value});
    }
    login(e) {
        e.preventDefault();
        const mainThis = this;
        if (mainThis.state.username && mainThis.state.password) {
            fetch('APILink')
            .then(function(response) {
                response.text().then(function(data) {
                    data = JSON.parse(data);
                    if (!data.error) {
                        mainThis.setState({redirectToDashboard:true});
                    } else {
                        alert(data.msg);
                    }
                })  
            })
        } else {
            alert('Username and Password needed');
        }
    }

    renderRedirect = () => {
        if (this.state.redirectToDashboard) {
            return <Redirect exact to='/company' />
        } else {
            return <Redirect exact to='/login' />

        }
     }

    render() {
        let renderedComp;
        return(
            <BrowserRouter 
                    basename='/'
                    forceRefresh={!supportsHistory}>
                <React.Fragment>
                    {this.renderRedirect()}
                    <Route exact path="/company" render={()=><Dashboard/>} />
                    <Route exact path="/login" render={()=><Login login={(e)=>this.login(e)} onChangeInput={(e)=>this.onChangeInput(e)} />} />
                </React.Fragment>
            </BrowserRouter>
        )
    }
}

这个组件的显示基于this.state.redirectToDashboard的值,但是由于:

onChangeInput(e) {
    this.setState({
        [e.target.name]:e.target.value
    });
}

每个输入都会重新呈现页面,留下以下内容:

警告:您尝试重定向到当前所在路由:“/login”

我知道是什么导致了这个警告,只是我想不出其他方法使其工作。我应该做出哪些更改或者至少有一个好的想法来使其正常工作呢?

你是否真的需要<Redirect exact to='/login' />组件呢?也许你可以直接在render方法中编写例如this.state.redirectToDashboard && <Redirect exact to='/company' /> - Tholle
请勿在 --> onChangeInput={(e)=>this.onChangeInput(e)} 中使用箭头函数。箭头函数会导致重新渲染。希望这能帮到您。 - tarzen chugh
@Tholle 我正在使用 <Redirect exact to='/login' />,这样当我打开 http://localhost:3000/ 时,它会重定向到 http://localhost:3000/login,而不是给我一个空白屏幕。 - Carl Binalla
@tarzenchugh,使用this.setState({[e.target.name]:e.target.value});仍会导致重新渲染吗?我也尝试将其更改为this.onChangeInput.bind(this),但出现了相同的错误。 - Carl Binalla
2个回答

2
您可以将您的组件包裹在Switch中,这样只有一个子元素会被渲染。
然后,您可以将从//login的重定向添加为第一个子元素,并在redirectToDashboardtrue时,将重定向到/company放在Switch之外。 示例:
<BrowserRouter basename="/" forceRefresh={!supportsHistory}>
  <div>
    {this.state.redirectToDashboard && <Redirect to="/company" />}
    <Switch>
      <Redirect exact from="/" to="/login" />
      <Route path="/company" component={Dashboard} />
      <Route
        path="/login"
        render={() => (
          <Login
            login={e => this.login(e)}
            onChangeInput={e => this.onChangeInput(e)}
          />
        )}
      />
    </Switch>
  </div>
</BrowserRouter>

这很不错,尽管在重定向到<Dashboard />后,似乎出现了相同的错误,现在链接是/company - Carl Binalla

0
也许当你的renderRedirect条件不匹配时,你不应该渲染重定向。

可以尝试这样做:

renderRedirect = () => {
    if (this.state.redirectToDashboard) {
        return <Redirect exact to='/company' />
    } else {
        return <Redirect exact to='/login' />
    }
 }

你可以待在那里:

renderRedirect = () => {
    if (this.state.redirectToDashboard) {
        return <Redirect exact to='/company' />
    }

    return null;
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接