React Router V4 - 页面不会在更改的路由上重新渲染

时间:2017-04-22 05:51:33

标签: reactjs react-router

我正在构建一个小应用程序来学习与Meteor的React。 要求用户输入一个位置,根据此位置将用户路由到新页面,其中位置显示在页面顶部,而某些数据来自数据库,基于该位置(尚未,这是我的下一步)。 我将位置存储在组件上的状态。如果用户可以更改位置,那就太好了。 这很简单:只需更新状态,evoilá。或者我想。现在的问题是URL没有更新,看起来很愚蠢。 然后我想:“好吧,让我们检查点击旧位置(处于状态)和新位置(来自输入)是否不同,如果是这样,设置重定向状态” 在我的渲染功能中,如果设置了重定向,我只会将用户再次路由到同一页面,但现在页面将不会重新加载。任何想法?

我知道现在反应路由器v4上有一千个问题,因为它们最近刚刚更新了版本。我一直在阅读最后几个小时的文档而且无法绕过它。

import React, { Component } from 'react';
import { Route, Redirect } from 'react-router'
import LocationPicker from './LocationPicker'

export default class LocationDisplay extends Component {
    constructor () {
        super();
        this.setLocation = this.setLocation.bind(this);
        this.state = {redirect: false};
    }

    setLocation(value) {
        this.setState({locationId: value});
        if (this.state.locationId != value) {
            this.setState({redirect : true})
        };
    }

    componentWillMount() {
        this.setState({
            locationId: this.props.match.params.locationId,
        });
    }

    render () {
        return (
            this.state.redirect 
            ? 
            <Redirect push to={{
                pathname: `/location/${this.state.locationId}`
            }}/> 
            :
            <div>
                <LocationPicker 
                    returnLocation={this.setLocation} 
                    locationId={this.state.locationId}
                />
                <h1>Please find below all recommendations for {this.state.locationId}</h1>
            </div>
        )
    }
}

在这里我的路线:

import React from 'react';
import {
  BrowserRouter as Router,
  Route,
  Link
} from 'react-router-dom';
import { render } from 'react-dom';

import App from './App';
import LocationPicker from './LocationPicker';
import LocationDisplay from './LocationDisplay';

Meteor.startup(() => {
    render(
        <Router>
            <div>
                <Route exact path="/" component={LocationPicker}/>
                <Route path="/location/:locationId" component={LocationDisplay}/>
            </div>
        </Router>,
         document.getElementById('render-target')
    );
});

更新

我尝试使用<Link>代替<Redirect>,但这具有相同的效果。更重要的是,它现在根本不更新URL。

render () {
        return (
            this.state.redirect 
            ? 
            <Link to={{
                pathname: `/location/${this.state.locationId}`
            }}/>
            :
            <div>
                <LocationPicker 
                    returnLocation={this.setLocation} 
                    locationId={this.state.locationId}
                />
                <h1>Please find bellow all recommendations for {this.state.locationId}</h1>
            </div>
        )
    }

对基本语言问题的任何解释也将非常感激。我还没到那里:(

干杯和thx很多

2 个答案:

答案 0 :(得分:3)

您只能通过更改state来改变路线。即使使用了<Redirect>方法,它也只能通过将this.state.redirect设置为true来进行无限重定向循环。因为Route对每个重定向使用相同的LocationDisplay实例,this.state.redirect将始终为true。但是,react-router会自动指示此重定向循环并呈现空白。

在react-router中更改路由的正确方法是在history对象中使用push方法。您只需使用新路径名称调用push方法,如下所示。

setLocation(value) {
  this.props.history.push(`/location/${value}`);
}

另外,我不明白为什么你将locationId保留在state中。它已经在props this.props.match.params.locationId。因此,没有必要在两个地方保留相同的数据,因为拥有单一的事实来源是理想的。否则,您始终必须编写其他代码行,以使locationIdstate同步props。所以我建议你改变你的做法。

export default class LocationDisplay extends Component {
  constructor () {
      super();
  }

  setLocation(value) {
    this.props.history.push(`/location/${value}`);
  }

  render () {
    const locationId = this.props.match.params.locationId
    return (
      <div>
        <LocationPicker 
          returnLocation={this.setLocation} 
          locationId={locationId}
        />
        <h1>Please find below all recommendations for {locationId}</h1>
      </div>
    )
  }
}

(这段代码只是为了得到一个想法。我没有测试此代码,因为我没有其他部分。如果您可以提供codepenjsfiddle当前实现我可以将其更新为工作。)

答案 1 :(得分:1)

对于遇到Redux问题的用户,请将connect包裹在withRouter内,如下所示:https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md