简体   繁体   English

react-router 与上下文 - 为什么它不能与锚点和链接一样工作

[英]react-router with context - why doesn't it work the same with anchor vs Link

I have the below sample code using react-router and context hooks where I am trying to understand why it behaves differently when I use anchors instead of Link components.我有以下使用 react-router 和上下文挂钩的示例代码,我试图理解为什么当我使用锚点而不是链接组件时它的行为会有所不同。 The Link components are commented out.链接组件被注释掉。

This app just simply displays a screen with an html link where you can click it to display component 2 (component 1 is displayed initially).这个应用程序只是简单地显示一个带有 html 链接的屏幕,您可以单击它以显示组件 2(最初显示组件 1)。 I am updating the context value in the onClick event for the anchor (I use the setName function to update the name in the context).我正在为锚更新 onClick 事件中的上下文值(我使用 setName function 来更新上下文中的名称)。

When I use anchor tags, it doesn't keep the context value that was updated.当我使用锚标签时,它不会保留更新的上下文值。 So when it goes to component2, the name value in the context displays as person1.因此,当它转到 component2 时,上下文中的名称值显示为 person1。 However, if I comment out the anchors and use the Link components instead, the context value is updated properly.但是,如果我注释掉锚点并改用 Link 组件,则上下文值会正确更新。

Why do the Link components work as expected but not the anchors when updating context?为什么更新上下文时链接组件按预期工作但锚点不工作?

import React, { useContext, useState } from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import { useHistory } from 'react-router-dom';

const NameContext = React.createContext();

function App() {
  const [name, setName] = useState('name1');

  return (
    <NameContext.Provider value={{ name, setName }}>
      <Router>
        <Route exact path="/" component={Component1} />
        <Route exact path="/component1" component={Component1} />
        <Route exact path="/component2" component={Component2} />
      </Router>
    </NameContext.Provider>
  );
}

function Component1() {
  const { name, setName } = useContext(NameContext);
  const history = useHistory();

  return (
    <>
      <div>This is component 1, name = {name}</div>
      <a href="/component2" onClick={() => setName('name2')}>
        Click to display component 2
      </a>
      {/* <Link
        onClick={() => setName('name2')}
        to={(location) => {
          return { ...location, pathname: '/component2' };
        }}
      >
        Click to display component 2
      </Link> */}
    </>
  );
}

function Component2() {
  const { name, setName } = useContext(NameContext);
  const history = useHistory();

  return (
    <>
      <div>This is component 2, name = {name}</div>
      <a href="/component1" onClick={() => setName('name3')}>
        Click to display component 1
      </a>
      {/* <Link
        onClick={() => setName('name3')}
        to={(location) => {
          return { ...location, pathname: '/component1' };
        }}
      >
        Click to display component 1
      </Link> */}
    </>
  );
}

export default App;

An anchor tag reloads the browser by default.默认情况下,锚标记会重新加载浏览器。 If you want to avoid this default behavior you can call the preventDefault method on the onClick event.如果您想避免这种默认行为,您可以在onClick事件上调用preventDefault方法。

react-router doesn't use anchor tags either, so if you want to use anchor tags you have to manually update the history. react-router也不使用锚标签,因此如果要使用锚标签,则必须手动更新历史记录。

<div>This is component 1, name = {name}</div>
<a
  href="/component2"
  onClick={(e) => {
    e.preventDefault();
    setName("name2");
    history.push("/component2");
  }}
>
  Click to display component 2
</a>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM