当前位置: 首页 > 面试题库 >

在根级别无法访问React Router v4嵌套匹配参数

蔚楷
2023-03-14
问题内容

测试用例

https://codesandbox.io/s/rr00y9w2wm

重现步骤

  • 点击主题
  • 点击React渲染

要么

  • 转到https://rr00y9w2wm.codesandbox.io/topics/rendering

预期行为

  • match.params.topicId应该是相同的来自两个亲本 的主题 组件应该是相同的match.params.topicId,当内访问 主题 部件

实际行为

  • match.params.topicIdTopic 组件内访问时 未定义
  • match.params.topicIdTopics 组件中访问时 呈现

从这个已解决的问题中我了解到,这不一定是错误。

在需要在工厂Web应用程序中创建运行的用户中,这种要求是非常普遍的,其中Topics父级组件需要访问 match.params.paramId
,其中paramIdURL参数与嵌套(子)组件相匹配Topic

    const Topic = ({ match }) => (
      <div>
        <h2>Topic ID param from Topic Components</h2>
        <h3>{match.params.topicId}</h3>
      </div>
    );

    const Topics = ({ match }) => (
      <div>
        <h2>Topics</h2>
        <h3>{match.params.topicId || "undefined"}</h3>
        <Route path={`${match.url}/:topicId`} component={Topic} />
        ...
      </div>
    );

从一般意义上讲,Topics它可以是“抽屉”或“导航菜单”组件,Topic也可以是任何子组件,就像我正在开发的应用程序中一样。子组件具有其自己的:topicId参数,该参数具有其自己(例如)<Route path="sections/:sectionId" component={Section} /> 路由/组件。

更加痛苦的是,导航菜单不必与组件树具有一对一的关系。有时,菜单根级的项目(例如TopicsSections等)可能与 嵌套
结构相对应(Sections仅在“主题”下呈现,/topics/:topicId/sections/:sectionId尽管它具有自己的标准化列表,用户可以在“导航
中的“标题 下找到该列表)酒吧)。因此,当 被点击, 应当强调,而不是两个 章节 主题

由于导航栏组件的sectionIdsections路径在应用程序的根目录级别不可用,因此对于这种常见的用例,有必要像这样编写hack。

我根本不是React Router的专家,因此,如果任何人都可以对此用例提出合适的优雅解决方案,我将认为这是富有成果的努力。优雅,我的意思是

  • 用途match与非history.location.pathname
  • 不涉及诸如手动解析 window.location.xxx
  • 不使用 this.props.location.pathname
  • 不使用像 path-to-regexp
  • 不使用查询参数

TIA!


问题答案:

尝试利用查询参数?来允许父级和子级访问当前选定的topic。不幸的是,您将需要使用模块qs,因为react- router-dom它不会自动解析查询(react-router v3可以)。

工作示例:https :
//codesandbox.io/s/my1ljx40r9

URL的结构类似于连接字符串:

topic?topic=props-v-state

然后您将添加到查询中&

/topics/topic?topic=optimization&category=pure- components&subcategory=shouldComponentUpdate

✔使用匹配进行路由URL处理

✔不使用this.props.location.pathname(使用this.props.location.search

✔用于qs解析location.search

✔不涉及骇客方法

Topics.js

    import React from "react";
    import { Link, Route } from "react-router-dom";
    import qs from "qs";
    import Topic from "./Topic";

    export default ({ match, location }) => {
      const { topic } = qs.parse(location.search, {
        ignoreQueryPrefix: true
      });

      return (
        <div>
          <h2>Topics</h2>
          <ul>
            <li>
              <Link to={`${match.url}/topic?topic=rendering`}>
                Rendering with React
              </Link>
            </li>
            <li>
              <Link to={`${match.url}/topic?topic=components`}>Components</Link>
            </li>
            <li>
              <Link to={`${match.url}/topic?topic=props-v-state`}>
                Props v. State
              </Link>
            </li>
          </ul>
          <h2>
            Topic ID param from Topic<strong>s</strong> Components
          </h2>
          <h3>{topic && topic}</h3>
          <Route
            path={`${match.url}/:topicId`}
            render={props => <Topic {...props} topic={topic} />}
          />
          <Route
            exact
            path={match.url}
            render={() => <h3>Please select a topic.</h3>}
          />
        </div>
      );
    };

另一种方法是创建一个HOC将参数存储到的state子项,state当子项的参数更改时,子项会更新其父项。

URL的结构类似于文件夹树: /topics/rendering/optimization/pure- components/shouldComponentUpdate

工作示例:https :
//codesandbox.io/s/9joknpm9jy

✔使用匹配进行路由URL处理

✔不使用 this.props.location.pathname

✔使用lodash进行对象间比较

✔不涉及骇客方法

Topics.js

    import map from "lodash/map";
    import React, { Fragment, Component } from "react";
    import NestedRoutes from "./NestedRoutes";
    import Links from "./Links";
    import createPath from "./createPath";

    export default class Topics extends Component {
      state = {
        params: "",
        paths: []
      };

      componentDidMount = () => {
        const urlPaths = [
          this.props.match.url,
          ":topicId",
          ":subcategory",
          ":item",
          ":lifecycles"
        ];
        this.setState({ paths: createPath(urlPaths) });
      };

      handleUrlChange = params => this.setState({ params });

      showParams = params =>
        !params
          ? null
          : map(params, name => <Fragment key={name}>{name} </Fragment>);

      render = () => (
        <div>
          <h2>Topics</h2>
          <Links match={this.props.match} />
          <h2>
            Topic ID param from Topic<strong>s</strong> Components
          </h2>
          <h3>{this.state.params && this.showParams(this.state.params)}</h3>
          <NestedRoutes
            handleUrlChange={this.handleUrlChange}
            match={this.props.match}
            paths={this.state.paths}
            showParams={this.showParams}
          />
        </div>
      );
    }

NestedRoutes.js

    import map from "lodash/map";
    import React, { Fragment } from "react";
    import { Route } from "react-router-dom";
    import Topic from "./Topic";

    export default ({ handleUrlChange, match, paths, showParams }) => (
      <Fragment>
        {map(paths, path => (
          <Route
            exact
            key={path}
            path={path}
            render={props => (
              <Topic
                {...props}
                handleUrlChange={handleUrlChange}
                showParams={showParams}
              />
            )}
          />
        ))}
        <Route
          exact
          path={match.url}
          render={() => <h3>Please select a topic.</h3>}
        />
      </Fragment>
    );


 类似资料:
  • https://codesandbox.io/s/rr00y9w2wm 单击主题 单击“使用React渲染” 或者 去https://rr00y9w2wm.codesandbox.io/topics/rendering 应与父主题组件相同,在主题组件中访问时应与相同 在主题组件中访问时未定义 我从这个已结束的问题中了解到,这不一定是一个bug。 这个需求在想要在工厂Web应用程序中创建运行的用户中

  • 目前我有这个阵列= 条件: 如果每个嵌套数组index2都相同,那么我想用[0.0 1.0,1.0 2.0,2.0 3.0,3.0 4.0] = [1.0,3.0,5.0,7.0]来求和 我想要的最终结果:[[“efg”, [1.0, 3.0, 5.0, 7.0], “测试”]] 有什么方法或建议来获得这个结果吗?

  • 我正在使用bootstrap和jQuery创建一个登陆页面。一个缺点是,我只能用jquery更改html,因为html是由cms后端代码硬编码的,更改后会重置html。因此操作代码的唯一方法是使用jQuery。长话短说,我有一个包含输入和标签的表单。我正在尝试将输入和标签标签的一列变成两列。到目前为止,我已经创建了一个具有自己的类的div标记,这将是第二列。使用jquery wrapAll函数,在

  • 我想访问嵌套集合属性与以下结构<代码>["角色"= 为了得到我想要的,我使用laravel集合方法通过执行

  • 该示例摘自Elasticsearch参考:https://www.elastic.co/guide/en/Elasticsearch/reference/5.3/nested.html 我的索引和这个差不多。唯一的区别是user.first和user.last是关键字类型,所以我可以对它们使用过滤器。 在两种情况下,我应该使用什么查询来获取与上面数组匹配的文档(正好是两个项,一个项是John Sm

  • 我试图创建一个正则表达式模式来匹配每个(内容*),但是该模式可以在另一个((内容)(内容))中找到。我尝试了,但这返回了外部的。 例如:字符串应返回: 第一个匹配: 第二个匹配: 编辑: 我试过:但在?R(未知标志)附近出现错误