Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

332
Visualizações
useState affects all instances of a Component

I have a simple component below named Idea:

import './Idea.css';
import { useState } from 'react';
import { useParams } from 'react-router-dom';

function Idea() {
  const { id } = useParams();
  const [ test, setTest ] = useState('');

  console.log('Idea rendered');

  const handleChange = (event) => {
    setTest(event.target.value);
  };
  
  return (
    <form>
      <input onChange={handleChange} value={test}/>
    </form>
  );
};

export default Idea;

Each instance of this component is rendered using react-router via dynamic routing, as shown in the second route component below:

function App() {
  return (
    <Provider store={store}>
      <BrowserRouter>
        <main>
          <SideBar />
          <section id='main-window'>
            <Routes>
              <Route exact path="/" element={ <Instructions /> } />
              <Route path="/ideas/:id" element={ <Idea/> } />
            </Routes>
          </section>
        </main>
      </BrowserRouter>
    </Provider>
  );
};

The problem is illustrated in this example: Let's say I am on route /ideas/1234 and its input value says hello world!. If I switch to route /ideas/5678 then the input on that route will also say hello world! even though I specified the input value to say otherwise upon render. If I change the input value on route /ideas/5678 the input value on route /input/1234 will change as well. They will inevitably both be the same value as if they're the same, regardless of the route. This started happening when I introduced the useState hook in the Idea component. I assume useState should reset the input value every time I change a route but this does not seem to happen.

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Here's the documentation for the useState hook: https://reactjs.org/docs/hooks-state.html

Here's the important part for your case:

What does calling useState do? It declares a “state variable”. ... This is a way to “preserve” some values between the function calls ... Normally, variables “disappear” when the function exits but state variables are preserved by React.

So by introducing useState hook to the Idea component, you are actually preserving the input value. If you want it to clear out based on a certain condition, like if the value of id from useParams has changed, look into useEffect hook. Maybe do something like:

useEffect(()=> {
    setTest('');
}, [id]);
about 4 years ago · Juan Pablo Isaza Relatório

0

Given route <Route path="/ideas/:id" element={<Idea />} /> when the route path param id changes the Route component doesn't unmount and mount a new instance of Idea as this would be wasteful, and instead it will simply rerender Idea with a new route path parameter provided from a routing context.

Think of this like any other React component where they rerender for one of three reasons:

  1. A state update was enqueued and trigger a component rerender.
  2. A prop value updated and triggered a component rerender.
  3. A component's parent component rerendered.

Your code is in the third case where the URL path changed and the Routes component matches the best Route component, and since <Route path="/ideas/:id" element={<Idea />} /> was already matched it rerenders, which rerenders Idea.

If the routed component needs to handle changes to the route params then it should use the useEffect hook to "listen" for them.

Example:

function Idea() {
  const { id } = useParams();
  const [test, setTest] = useState('');

  useEffect(() => {
    console.log('Idea rendered');
  });

  useEffect(() => {
    console.log('id updated', { id });
    setTest('');
  }, [id]);

  const handleChange = (event) => {
    setTest(event.target.value);
  };
  
  return (
    <form>
      <input onChange={handleChange} value={test} />
    </form>
  );
};

An alternative to listening to changes is to create a wrapper component that uses the route param as a React key on the routed component. Using this method will unmount and mount a new component instance.

Example:

const IdeaWrapper = () => {
  const { id } = useParams();
  return <Idea key={id} />;
};

...

<Routes>
  <Route exact path="/" element={<Instructions />} />
  <Route path="/ideas/:id" element={<IdeaWrapper />} />
</Routes>

If you wanted, you could even create a custom state hook that resets on dependency updates.

Example:

const useResetState = (initialState, deps) => {
  const [state, setState] = useState(initialState);
  useEffect(() => {
    setState(initialState);
  }, deps);

  return [state, setState];
};

...

function Idea() {
  const { id } = useParams();

  const [test, setTest] = useResetState('', [id]); // <-- resets when id updates

  useEffect(() => {
    console.log('Idea rendered');
  });

  const handleChange = (event) => {
    setTest(event.target.value);
  };
  
  return (
    <form>
      <input onChange={handleChange} value={test} />
    </form>
  );
};
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda