【问题标题】:React-router URL changes but page is still unchangedReact-router URL 更改,但页面仍未更改
【发布时间】:2021-07-31 05:44:43
【问题描述】:

我是 react 和 react-router 的新手,所以请放轻松。

我正在尝试在我的 Todo List 项目中实现路由器,其中 path="/" 将我带到我的 todo 列表,而 path="/id" 将我带到测试页面(稍后将显示任务的描述) .

当我单击将我带到“/id”的链接时,浏览器中的 URL 会发生变化,但页面/内容不会。但是,当我刷新浏览器时,会加载测试页面。

我已将 Switch 放入 App.js 中,如下所示。

import React, { Component } from "react";
import "./App.css";
import TodoList from "./components/TodoList";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Test from "./components/Test";

class App extends Component {
  render() {
    return (
      <Router>
        <div className="todo-app">
          <p>
            <Link to="/">Home</Link>
          </p>
          <Switch>
            <Route exact path="/" component={TodoList} />
            <Route path={`/id`} component={Test} />
          </Switch>
        </div>
      </Router>
    );
  }
}

export default App;

并且我已将指向“/id”的链接放在 App.js 中调用的组件的子组件中,如下所示。

<div key={todo.id}>
    <Link className="todo-text" to={`/id/${todo.id}`}>
      {todo.text}
    </Link>
</div>

我是否遗漏了导致我的组件在单击链接时无法加载的内容?

编辑:这是我的项目的链接。 https://stackblitz.com/edit/react-7cpjp9?file=src/index.js

【问题讨论】:

  • 正在呈现“/id”路由的链接在哪里,它们是如何呈现的?你能分享那个组件代码吗?路由路径不应该是 "/id/:id" 之类的东西来匹配链接到它的计算 URL/路径吗?
  • @DrewReese 我们可以做“/id/:id”,我不知道这是可能的。我已经改变了,但问题仍然是一样的。我已经在上面的编辑中链接了我的项目,请您检查一下并帮助我可能做错了什么?

标签: reactjs react-router-dom


【解决方案1】:

问题

好的,这个问题正是我所怀疑的。您正在应用程序中渲染多个路由器。第一个是 index.js 文件中的 BrowserRouter,第二个,App.js 中的另一个 BrowserRouter,以及 Todo.js 中至少第三个 BrowserRouter。您只需要一个路由器即可为整个应用提供路由上下文。

这里的问题是Todo 组件中的路由器是最接近特定待办事项详细信息链接的路由器上下文。当点击Todo 中的链接时,这个最近的路由器会处理导航请求并更新地址栏中的 URL。块或“掩码”,App 组件或 index.js 中的路由器,从“看到”导航操作发生而呈现路由。换句话说,地址栏中的 URL 由内部路由器更新,但外部路由器不知道要渲染不同的路由。

解决方案

在 index.js 中保留 BrowserRouter 包装 App 并删除您应用中使用的所有其他路由器。

App - 移除 Router 组件。此外,将路线/路径从最具体到最不具体重新排序,这样您就不需要在每条路线上指定 exact 属性。允许Switch 组件在不太具体的路径之前匹配和渲染更具体的路径。

class App extends Component {
  render() {
    return (
      <div className="todo-app">
        <p>
          <Link to="/">Home</Link>
        </p>
        <Switch>
          <Route path="/id/:todoId" component={Test} />
          <Route path="/" component={TodoList} />
        </Switch>
      </div>
    );
  }
}

Todo - 删除 Router 组件。将 key={todo.id} 移动到最外层的元素,这样当 todos 数组更新时,React 可以协调更新。

class Todo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      id: null,
      value: "",
      details: "",
    };
    this.submitUpdate = this.submitUpdate.bind(this);
  }

  submitUpdate(value) {
    const { updateTodo } = this.props;
    updateTodo(this.state.id, value);
    this.setState({
      id: null,
      value: "",
    });
  }

  render() {
    const { todos, completeTodo, removeTodo } = this.props;
    if (this.state.id) {
      return <TodoForm edit={this.state} onSubmit={this.submitUpdate} />;
    }

    return todos.map((todo, index) => (
      <div
        className={todo.isComplete ? "todo-row complete" : "todo-row"}
        key={todo.id}
      >
        <div>
          <Link className="todo-text" to={`/id/${todo.id}`}>
            {todo.text}
          </Link>
        </div>
        <div className="icons">
          <RiCloseCircleLine
            onClick={() => removeTodo(todo.id)}
            className="delete-icon"
          />
          <TiEdit
            onClick={() => this.setState({ id: todo.id, value: todo.text })}
            className="edit-icon"
          />
          <RiCheckboxCircleLine
            onClick={() => completeTodo(todo.id)}
            className="delete-icon"
          />
        </div>
      </div>
    ));
  }
}

【讨论】:

  • 非常感谢!!我正在从 youtube 教程中学习路由器,所以我没有意识到我不应该多次使用 BrowserRouter,我修复了我的路由。谢谢!!
【解决方案2】:

首先,你对动态路由采取的做法是错误的。 应该是这样,您必须在动态路由上添加确切的关键字。

<Route exact path="/id/:todoId" component={Test} />

<div key={todo.id}>
<Link className="todo-text" to={`/id/${todo.id}`}>
  {todo.text}
</Link>

【讨论】:

  • "/id" 是 "/id/:todoId" 的路径前缀,因此计算的路径将/应该匹配和渲染。 match 参数在组件中渲染后很有用。 OP 说组件没有被渲染,所以我不怀疑这是问题也不是修复。此外,当您使用Switch 组件时,如果您正确订购路线,您几乎从不需要在Route 组件上指定exact 属性,因为@987654326 @ 完全匹配。
【解决方案3】:
import React, { Component } from "react";
import "./App.css";
import TodoList from "./components/TodoList";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Test from "./components/Test";

class App extends Component {
  render() {
    return (
      <Router>
        <div className="todo-app">
          <p>
            <Link to="/">Home</Link>
          </p>
          <Switch>
            <Route exact path="/" component={TodoList} />
            **<Route exact path={`/id`} component={Test} />**
          </Switch>
        </div>
      </Router>
    );
  }
}

export default App;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-10
    • 2023-01-12
    • 2021-08-10
    • 2011-04-27
    • 2020-02-12
    • 2020-04-07
    • 2019-11-30
    • 1970-01-01
    相关资源
    最近更新 更多