【问题标题】:react js router route to outside router in nested router将js路由器路由反应到嵌套路由器中的外部路由器
【发布时间】:2020-11-07 18:19:03
【问题描述】:

我对嵌套的 react-router-dom 有疑问。我想从内部路由器到外部路由器。不知道怎么解释,这里举个例子吧。

https://codesandbox.io/s/react-router-preventing-transitions-forked-vmt4c?fontsize=14&hidenavigation=1&theme=dark

我在这里要做的是通过单击“根”按钮从主题组件路由回“/”(BlockingForm 组件)。

我该如何解决这个问题?

import React, { useState } from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  Prompt,
  useParams,
  useRouteMatch
} from "react-router-dom";

// Sometimes you want to prevent the user from
// navigating away from a page. The most common
// use case is when they have entered some data
// into a form but haven't submitted it yet, and
// you don't want them to lose it.

export default function PreventingTransitionsExample() {
  return (
    <Router>
      <ul>
        <li>
          <Link to="/">Form</Link>
        </li>
        <li>
          <Link to="/home">home</Link>
        </li>
        <li>
          <Link to="/one">One</Link>
        </li>
        <li>
          <Link to="/two">Two</Link>
        </li>
      </ul>

      <Switch>
        <Route path="/" exact children={<BlockingForm />} />
        <Route path="/home" exact children={<NestingExample />} />
        <Route path="/one" children={<h3>One</h3>} />
        <Route path="/two" children={<h3>Two</h3>} />
      </Switch>
    </Router>
  );
}

function NestingExample() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/home">Home</Link>
          </li>
          <li>
            <Link to="home/topics">Topics</Link>
          </li>
        </ul>

        <hr />

        <Switch>
          <Route exact path="/home/">
            <Home />
          </Route>
          <Route path="/home/topics">
            <Topics />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

function Home() {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}

function Topics() {
  // The `path` lets us build <Route> paths that are
  // relative to the parent route, while the `url` lets
  // us build relative links.
  let { path, url } = useRouteMatch();

  return (
    <div>
      <h2>Topics</h2>
      <ul>
        <li>
          <Link to={`${url}/rendering`}>Rendering with React</Link>
        </li>
        <li>
          <Link to={`${url}/components`}>Components</Link>
        </li>
        <li>
          <Link to={`${url}/props-v-state`}>Props v. State</Link>
        </li>
        <li>
          <Link to={"/"}>Go root</Link>
        </li>
      </ul>

      <Switch>
        <Route exact path={path}>
          <h3>Please select a topic.</h3>
        </Route>
        <Route path={`${path}/:topicId`}>
          <Topic />
        </Route>
      </Switch>
    </div>
  );
}

function Topic() {
  // The <Route> that rendered this component has a
  // path of `/topics/:topicId`. The `:topicId` portion
  // of the URL indicates a placeholder that we can
  // get from `useParams()`.
  let { topicId } = useParams();

  return (
    <div>
      <h3>{topicId}</h3>
    </div>
  );
}

function BlockingForm() {
  let [isBlocking, setIsBlocking] = useState(false);

  return (
    <form
      onSubmit={(event) => {
        event.preventDefault();
        event.target.reset();
        setIsBlocking(false);
      }}
    >
      <Prompt
        when={isBlocking}
        message={(location) =>
          `Are you sure you want to go to ${location.pathname}`
        }
      />

      <p>
        Blocking? {isBlocking ? "Yes, click a link or the back button" : "Nope"}
      </p>

      <p>
        <input
          size="50"
          placeholder="type something to block transitions"
          onChange={(event) => {
            setIsBlocking(event.target.value.length > 0);
          }}
        />
      </p>

      <p>
        <button>Submit to stop blocking</button>
      </p>
    </form>
  );
}

【问题讨论】:

    标签: reactjs react-router nested-routes


    【解决方案1】:

    您可以通过使用 useHistory 来操作父路由器来实现这一点 :) 参考: https://reactrouter.com/web/api/Hooks/usehistory

    我只更改了嵌套路由器,以便向您展示如何更改父路由器位置:)

    import React, { useState } from "react";
    import {
      BrowserRouter as Router,
      Switch,
      Route,
      Link,
      Prompt,
      useParams,
      useRouteMatch,
      useHistory
    } from "react-router-dom";
    
    export default function PreventingTransitionsExample() {
      return (
        <Router>
          <ul>
            <li>
              <Link to="/">Form</Link>
            </li>
            <li>
              <Link to="/home">home</Link>
            </li>
            <li>
              <Link to="/one">One</Link>
            </li>
            <li>
              <Link to="/two">Two</Link>
            </li>
          </ul>
    
          <Switch>
            <Route path="/" exact children={<BlockingForm />} />
            <Route path="/home" exact children={<NestingExample />} />
            <Route path="/one" children={<h3>One</h3>} />
            <Route path="/two" children={<h3>Two</h3>} />
          </Switch>
        </Router>
      );
    }
        
     function NestingExample() {
    //use useHistory hook to get the history context from parent router
      const history = useHistory();
    //use this function on a onClick event instead of <link> to change the parent router
      const changeParentRouter = (url) => history.push(url);
      return (
        <Router>
          <div>
            <ul>
              <li>
                <Link to="/home">Home</Link>
              </li>
              <li>
                <Link to="home/topics">Topics</Link>
              </li>
            </ul>
    
            <hr />
    
            <Switch>
              <Route exact path="/home/">
                <Home />
              </Route>
              <Route path="/home/topics">
                <Topics />
              </Route>
            </Switch>
          </div>
        </Router>
      );
    }
    

    【讨论】:

    • 感谢您的回答。我使用历史测试路由,但它的工作方式与以前相同。
    猜你喜欢
    • 2019-02-18
    • 2016-08-18
    • 1970-01-01
    • 2019-01-12
    • 2017-07-23
    • 2017-08-06
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    相关资源
    最近更新 更多