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" },
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.Cela fera que l'optimisation RRD fonctionnera pour vous, pas contre vous.
Si vous n'avez pas de
. Notez que cela couple une certaine logique de composant interne avec des détails externes.name
这样的传递道具可以从中获取提示,则可以使用location.pathname
j'aimeCela fonctionne avec
Switch
dans React-Router-DomEn 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
Tab
或Route
上。我通常将其添加到Route
car cela a plus de sens à mon avis :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.