反应路由器链接在同一路径上访问时不会导致重新渲染

Hok*_*imo 5 javascript ecmascript-6 reactjs react-router

我正在使用 react router v4,在重新加载页面(不是 window.location.reload)时遇到了一些问题。我最好给出一个真实的用例来解释这个问题,我们以一个社交网络应用程序为例:

  1. 用户 A 评论了用户 B 的帖子,通知出现在用户 B 页面中。
  2. 用户 B 点击了通知,我们这样做了this.props.history.push('/job/' + id'),它起作用了,因此用户 B 转到了job/123页面。
  3. 用户A再次评论,新的通知出现在用户B页面,而用户B还在job/123页面上,他点击了通知链接并触发了this.props.history.push('/job' + id')。但是他不会看到页面重新呈现,他也没有看到最新的评论,因为该页面什么都不做。

mja*_*son 1

您正在描述两种不同类型的状态变化。

在第一种情况下,当用户 B 不在页面/job/:id时,他单击一个链接,您会看到 URL 更改,这会触发路由器中的状态更改,并将该更改传播到您的组件,以便您可以看到评论。

在第二种情况下,当用户 B 已经/job/:id页面并且有新评论通过时,URL 不需要更改,因此单击链接不会更改 URL,也不会触发页面中的状态更改路由器,因此您将看不到新内容。

我可能会尝试这样的事情(伪代码,因为我不知道你如何获得新评论或通过 websocket 订阅):

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

class Home extends React.Component {
  render() {
    return (
      <div>
        <h1>The home page</h1>

        {/* This is the link that the user sees when someone makes a new comment */}
        <Link to="/job/123">See the new comment!</Link>
      </div>
    );
  }
}

class Job extends React.Component {
  state = { comments: [] };

  fetchComments() {
    // Fetch the comments for this job from the server,
    // using the id from the URL.
    fetchTheComments(this.props.params.id, comments => {
      this.setState({ comments });
    });
  }

  componentDidMount() {
    // Fetch the comments once when we first mount.
    this.fetchComments();

    // Setup a listener (websocket) to listen for more comments. When
    // we get a notification, re-fetch the comments.
    listenForNotifications(() => {
      this.fetchComments();
    });
  }

  render() {
    return (
      <div>
        <h1>Job {this.props.params.id}</h1>
        <ul>
          {this.state.comments.map(comment => (
            <li key={comment.id}>{comment.text}</li>
          ))}
        </ul>
      </div>
    );
  }
}

ReactDOM.render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/job/:id" component={Job} />
    </Switch>
  </BrowserRouter>,
  document.getElementById("app")
);
Run Code Online (Sandbox Code Playgroud)

现在,页面将在两种情况下更新。