简体   繁体   English

反应路由器V4 - 路由更改的初始状态

[英]React Router V4 - Initial State on Route Change

Learning about React Router I noticed that a component will go back to its initial state when switching from route a to b . 了解React Router我发现当从路由a切换到b时,组件将返回其初始状态。

Why the same doesn't happen when clicking over again on the same route ie a to a ? 为什么在同一条路线上再次点击时也不会发生同样的情况,即a到a

How could I implement a way where clicking on the same route <NavLink/> the component reverts to its original state - Should/Could that be done on the onChange hook of React Router? 我怎样才能实现一种方法,点击相同的路径<NavLink/>组件恢复到原始状态 - 应该/可以在React路由器的onChange挂钩上完成吗?

If this is an anti-pattern please enlighten me on how else I could accomplish the following: I need my component to revert to its original state not only when switching routes but also in the case that a user chooses to click on the same route again. 如果这是一个反模式,请告诉我如何完成以下任务:我需要我的组件不仅在切换路由时还原到其原始状态,而且在用户选择再次点击同一路由的情况下。

Below, an abstraction of the issue: 下面是问题的抽象:

Clicking on the Cat <p/> tag should change its color to green , clicking on the same route <NavLink to="/cat-view">cat</NavLink> should revert the cat color state back to its initial state. 单击Cat <p/>标签应将其颜色更改为green ,单击相同的路径<NavLink to="/cat-view">cat</NavLink>应将cat颜色状态恢复为其初始状态。 ie color: false color: false

Just like it does when switching from route a to b (in my case cat to dog) 就像从路线a切换到b (在我的情况下是猫到狗)时一样

// Cat Component
import React, { useState } from "react";

export const Cat = () => {
  const [color, setColor] = useState(false);

  function ChangeColor() {
    setColor(true);
  }

  console.log(color)

  return (
    <p onClick={ChangeColor}>
      Click on this <span className={color ? "green" : " "}>Cat</span>
    </p>
  );
};

import {
  BrowserRouter as Router,
  Route,
  NavLink,
  Switch,
  withRouter,
  browserHistory
} from "react-router-dom";

// Main Component
class PetShop extends Component {
  state = {};

  render() {
    return (
      <Router history={browserHistory}>
        <div>
          <ul>
            <li>
              <NavLink to="/">home</NavLink>
            </li>
            <li>
              <NavLink to="/cat-view">cat</NavLink>
            </li>
            <li>
              <NavLink to="/dog-view">dog</NavLink>
            </li>
          </ul>

          <Switch>
            <Route
              path="/cat-view"
              render={() => <Cat/>}
              onChange={console.log("cat route changed")}
            />
            <Route
              path="/dog-view"
              render={() => <Dog/>}
              onChange={console.log("dog route changed")}
            />
          </Switch>
        </div>
      </Router>
    );
  }
}

export default withRouter(PetShop);

here's a code sandbox 这是一个代码沙箱

Since you are using the react-router Switch component which only renders the first match, when you switch from Route a to b , a is being unmounted; 由于您使用的反应路由器Switch组件仅呈现第一个匹配项,因此当您从路由a切换到b时卸载a; this tosses out all of its state so if you switch back to a you have a brand new component that gets the initial value you have specified for its state (eg false for Cat color ). 这会抛弃它的所有状态,所以如果你切换回a你有一个全新的组件,它获得你为其状态指定的初始值(例如,对于Cat colorfalse )。 Clicking on a NavLink that doesn't change the rendered Route leaves the same element in place and has no effect on its state. 点击一个NavLink不改变所呈现的Route离开到位相同的元素,并且在其状态没有影响。

If you want to change the state when you click on its NavLink , then you need to explicitly do that. 如果要在单击其NavLink时更改状态,则需要明确执行此操作。 There are two main ways you could do this: 有两种主要方法可以做到这一点:

  • lift the state up to the parent and explicitly change it on click of the link 将状态提升到父级并在单击链接时显式更改它
  • change the key of the element to force a remounting 更改元素的键以强制重新安装
  • provide a mechanism for the parent to reach into the child and tell it to reset its state 为父母提供一种机制,让他们进入孩子并告诉孩子重置其状态

Here's a modified version of your sandbox that demonstrates all of these: 这是沙盒的修改版本,演示了所有这些:

编辑react-remount-route

Cat demonstrates the first approach. Cat演示了第一种方法。

I've moved the state from Cat up to PetShop (Cat now just uses props). 我把州从Cat搬到PetShop (Cat现在只使用道具)。 I also added an onClick to the NavLink for cat that sets the state back to false . 我还在NavLink添加了一个onClick ,将状态设置为false

Dog demonstrates the second approach. Dog演示了第二种方法。

This approach would work better in a more complicated scenario where the component has lots of its own state and you want it all to reset if you click on the link again. 这种方法在更复杂的情况下可以更好地工作,其中组件具有许多自己的状态,并且如果再次单击链接,则希望全部重置。

Bunny demonstrates the third approach. Bunny演示了第三种方法。

This is similar to the key property for the Dog example, but doesn't cause a remount. 这类似于Dog示例的关键属性,但不会导致重新安装。 Bunny just uses the resetIndex in an effect to cause Bunny to reset itself. Bunny只是在效果中使用resetIndex来使Bunny重置自己。 There are probably several technical approaches for this. 可能有几种技术方法。 You just want a way to signal the child to reset itself. 你只想要一种方法来指示孩子重置自己。

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

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