【问题标题】:react router dom is not updating class component when url changeurl更改时反应路由器dom没有更新类组件
【发布时间】:2020-05-21 19:08:46
【问题描述】:

我是 ReactJS 的初学者。我想问一下当 URL 参数发生变化时更新组件的正确方法是什么。

当 URL 从 customer/1 更改为 customer/2 时,我的代码不会更新 CustomerDetails 组件。

import React from "react";
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import { CustomerList } from "./components/Customer/List";
import { CustomerDetails } from "./components/Customer/Details";

export class App extends React.Component<{}> {
  render(): React.ReactNode {
    return (
      <Router>
        <div>
          <nav>
            <li>
              <Link to="/customer">User list</Link>
            </li>
            <li>
              <Link to="/customer/1">Test Customer details 1</Link>
            </li>
            <li>
              <Link to="/customer/2">Test Customer Details 2</Link>
            </li>
          </nav>
          <Switch>
            <Route path="/customer/:customerId" component={CustomerDetails} />
            <Route path="/customer" component={CustomerList} />
          </Switch>
        </div>
      </Router>
    );
  }
}

我的CustomerDetails 类组件如下所示。

import * as React from "react";
import { RouteComponentProps } from "react-router-dom";

export interface CustomerDetailsParams {
  customerId: string;
}

export interface CustomerDetailsProps extends RouteComponentProps<CustomerDetailsParams> {
}

export interface CustomerDetailsState {
  customerId: string;
}

export class CustomerDetails extends React.Component<CustomerDetailsProps, CustomerDetailsState> {

  constructor(props: CustomerDetailsProps) {
    super(props);
    const params: CustomerDetailsParams = props.match.params;
    this.state = {
      customerId: params.customerId
    };
  }

  render(): React.ReactNode {
    return (
      <div className="customer-detail">
        <h2>customer details id: {this.state.customerId}</h2>
      </div>
    );
  }

}

为什么Route 组件没有重新创建CustomerDetails 组件?它是如何工作的?当我仅在 customer/1customer/2 链接之间切换时,这不起作用。

我正在使用react-router-dom@5.1.2react@16.12.0react-dom@16.12.0

【问题讨论】:

    标签: reactjs typescript react-router react-router-dom


    【解决方案1】:

    您在CustomerDetails 的构造函数中设置状态,但从不更新它。所以就组件而言,没有任何改变,也不需要更新。

    你可能根本不需要 state 中的那个重复的 prop,可以像这样直接在 props 中引用它:

    <h2>customer details id: {this.props.match.params.customerId}</h2>
    

    然后它会按预期更新。

    【讨论】:

    • 我在 React 文档中读到,我们不应该在安装组件时更改 props。只有状态应该使用setState 方法更改。所以我很感兴趣我应该如何根据良好的实践来设计它。这是一个非常简单的例子,但是如果基于这个customerId 我需要从 api 加载一些数据呢?
    • 你永远不应该修改props(至少不能直接修改),但在这里我们不会改变props,只是读取它。如果您需要从 prop 中读取以从 api 中获取,这将工作得很好。由于这个 prop 是一个路由参数,它应该只在 URL 改变时才会改变,而且你永远不需要调用 setState
    • 你是对的。我没有更改它,但Route 组件正在安装的组件上更改它。这是否意味着我的父组件Route 正在为其子组件CustomerDetails 更改道具?如何对组件中更改的道具做出反应,以便我可以从 api 加载数据?
    • 您可以在 componentDidUpdate 生命周期方法中执行此操作。只需添加类似if (prevProps.match.params.customerId != this.props.match.params.customerId) { //make api call with this.props..
    • 我刚刚发现了这张很棒的备忘单:projects.wojtekmaj.pl/react-lifecycle-methods-diagram 它解释了一切。非常感谢:)
    【解决方案2】:

    我猜你可能使用LinkRouteexact 属性来声明/customer 路由仅适用于CustomerList 组件,因此,你应该像下面这样写:

      <nav>
        <li>
          <Link exact to="/customer">User list</Link>
        </li>
        <li>
          <Link to="/customer/1">Test Customer details 1</Link>
        </li>
        <li>
          <Link to="/customer/2">Test Customer Details 2</Link>
        </li>
      </nav>
    

    并且还在Route 上使用:

      <Switch>
        <Route exact path="/customer" component={CustomerList} />
        <Route path="/customer/:customerId" component={CustomerDetails} />
      </Switch>
    

    【讨论】:

      猜你喜欢
      • 2018-01-05
      • 2023-03-31
      • 2018-11-13
      • 1970-01-01
      • 2017-02-23
      • 2020-05-16
      • 2019-11-29
      • 1970-01-01
      • 2016-10-26
      相关资源
      最近更新 更多