Pourquoi useState est-il partagé entre les routes avec différents accessoires ?
P粉571233520
P粉571233520 2024-03-30 21:19:56
0
2
393

J'ai une application avec deux onglets « Apple » et « Banane ». Chaque onglet dispose d'un compteur implémenté à l'aide de useState.

const Tab = ({ name, children = [] }) => {
  const id = uuid();
  const [ count, setCount ] = useState(0);

  const onClick = e => {
    e.preventDefault();
    setCount(c => c + 1);
  };

  const style = {
    background: "cyan",
    margin: "1em",
  };

  return (
    <section style={style}>
      <h2>{name} Tab</h2>
      <p>Render ID: {id}</p>
      <p>Counter: {count}</p>
      <button onClick={onClick}>+1</button>
      {children}
    </section>
  );
};

Certainement, le statut du compteur est partagé entre les deux onglets !

Si j'incrémente le compteur sur un onglet puis que je passe à un autre onglet, le compteur change également.

Pourquoi est-ce ?


Voici mon application complète :

import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { v4 as uuid } from "uuid";
import { HashRouter as Router, Switch, Route, Link } from "react-router-dom";

const Tab = ({ name, children = [] }) => {
  const id = uuid();
  const [ count, setCount ] = useState(0);

  const onClick = e => {
    e.preventDefault();
    setCount(c => c + 1);
  };

  const style = {
    background: "cyan",
    margin: "1em",
  };

  return (
    <section style={style}>
      <h2>{name} Tab</h2>
      <p>Render ID: {id}</p>
      <p>Counter: {count}</p>
      <button onClick={onClick}>+1</button>
      {children}
    </section>
  );
};

const App = () => {
  const id = uuid();

  return (
    <Router>
      <h1>Hello world</h1>
      <p>Render ID: {id}</p>
      <ul>
        <li>
          <Link to="/apple">Apple</Link>
        </li>
        <li>
          <Link to="/banana">Banana</Link>
        </li>
      </ul>
      <Switch>
        <Route
          path="/apple"
          exact={true}
          render={() => {
            return <Tab name="Apple" />;
          }}
        />
        <Route
          path="/banana"
          exact={true}
          render={() => {
            return <Tab name="Banana" />;
          }}
        />
      </Switch>
    </Router>
  );
};

const container = document.getElementById("root");
const root = createRoot(container);

root.render(<App />);

Version :

  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router": "5.2.1",
    "react-router-dom": "5.2.1",
    "uuid": "^9.0.0"
  },

P粉571233520
P粉571233520

répondre à tous(2)
P粉496886646

Adam a une bonne explication et une bonne réponse sur ce qui se passe ici, c'est une optimisation qui ne supprime pas et ne réinstalle pas le même composant React simplement parce que le chemin de l'URL change. L'utilisation des clés React résoudra certainement ce problème, forçant React à remonter l'état Tab 组件,从而“重置”count.

Je suggère d'utiliser une autre méthode lorsque name 属性从 "apple" 更改为 "banana" 时,保持挂载路由组件并简单地重置 count indique et vice versa.

const Tab = ({ name, children = [] }) => {
  const id = uuid();
  const [count, setCount] = useState(0);

  useEffect(() => {
    setCount(0); //  {
    e.preventDefault();
    setCount(c => c + 1);
  };

  const style = {
    background: "cyan",
    margin: "1em",
  };

  return (
    

{name} Tab

Render ID: {id}

Counter: {count}

{children}
); };

Cela fera que l'optimisation RRD fonctionnera pour vous, pas contre vous.

Si vous n'avez pas de name 这样的传递道具可以从中获取提示,则可以使用 location.pathnamej'aime

. Notez que cela couple une certaine logique de composant interne avec des détails externes.

Exemple : 🎜
const { pathname } = useLocation();
const [count, setCount] = useState(0);

useEffect(() => {
  setCount(0);
}, [pathname, setCount]);
P粉608647033

Cela fonctionne avec Switch dans React-Router-Dom

En fin de compte, votre arborescence de composants reste la même même si vous changez d'itinéraire.

Toujours routeur -> Switch -> Routage -> Onglet

En raison du fonctionnement de Switch, React n'installe jamais de nouveaux composants, il réutilise simplement l'ancienne arborescence parce qu'il le peut.

J'ai déjà eu ce problème et la solution était d'ajouter une clé quelque part, par exemple dans TabRoute 上。我通常将其添加到 Route car cela a plus de sens à mon avis :


         {
            return ;
          }}
        />
         {
            return ;
          }}
        />
      

Découvrez ce stack blitz :

https://stackblitz.com/edit/react-gj5mcv ?file=src/App.js

Bien entendu, votre état sera réinitialisé dans chaque onglet lorsque chaque onglet sera déchargé, ce qui peut être idéal ou non. Mais la solution à ce problème est bien sûr (si cela vous pose un problème), comme d’habitude, d’améliorer votre statut.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!