最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Router V4 - Initial State on Route Change - Stack Overflow

programmeradmin1浏览0评论

Learning about React Router I noticed that a ponent will go back to its initial state when switching from route a to b.

Why the same doesn't happen when clicking over again on the same route i.e a to a?

How could I implement a way where clicking on the same route <NavLink/> the ponent reverts to its original state - Should/Could that be done on the onChange hook of React Router?

If this is an anti-pattern please enlighten me on how else I could acplish the following: I need my ponent 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. i.e color: false

Just like it does when switching from route a to b (in my case cat to dog)

// 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

Learning about React Router I noticed that a ponent will go back to its initial state when switching from route a to b.

Why the same doesn't happen when clicking over again on the same route i.e a to a?

How could I implement a way where clicking on the same route <NavLink/> the ponent reverts to its original state - Should/Could that be done on the onChange hook of React Router?

If this is an anti-pattern please enlighten me on how else I could acplish the following: I need my ponent 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. i.e color: false

Just like it does when switching from route a to b (in my case cat to dog)

// 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

Share Improve this question edited Jan 22, 2019 at 19:33 Jonca33 asked Jan 22, 2019 at 19:27 Jonca33Jonca33 3,4937 gold badges28 silver badges39 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

Since you are using the react-router Switch ponent which only renders the first match, when you switch from Route a to b, a is being unmounted; this tosses out all of its state so if you switch back to a you have a brand new ponent that gets the initial value you have specified for its state (e.g. false for Cat color). Clicking on a NavLink that doesn't change the rendered Route leaves the same element in place and has no effect on its state.

If you want to change the state when you click on its NavLink, then you need to explicitly do that. 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:

Cat demonstrates the first approach.

I've moved the state from Cat up to PetShop (Cat now just uses props). I also added an onClick to the NavLink for cat that sets the state back to false.

Dog demonstrates the second approach.

This approach would work better in a more plicated scenario where the ponent 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.

This is similar to the key property for the Dog example, but doesn't cause a remount. Bunny just uses the resetIndex in an effect to cause Bunny to reset itself. There are probably several technical approaches for this. You just want a way to signal the child to reset itself.

发布评论

评论列表(0)

  1. 暂无评论