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

207
Visualizações
Is it ok to use useState hook setter to retrieve data, to avoid re-renders?

Short story

I want to know if this is ok to do:

  const onClick = useCallback(() => {
     setHoveredItem((hovered)=>{
       setSelectedData(hovered);
       return hovered;
     });
  },[]);

Just using the useState setter to get the value, 'removing' the useCallback's dependency to avoid re-renders. Notice the empty dependency array. Is that an acceptable way to do things?

Long story

I am working on an application with an chart. Re-renders to the chart are really bad (they basically break). So I used React.memo. All good until I needed to pass event listeners:

<MemoChart
    {...{ data, onHover, onClick }}>
</MemoChart>

On click, I want to store the hovered item.

Initially, this was my onClick function:

  const onClick = () => {
    setSelectedData(hoveredItem);
  }

But of course, every hover event re-renders the parent, which causes the chart to re-render. Use Callback on onClick would work, except that if I add a dependency on hoveredItem, it will do nothing.

So this is what I did. It works, but I have never seen it done and I wonder if it is ok to do:

  const onClick = useCallback(() => {
     setHoveredItem((hovered)=>{
       setSelectedData(hovered);
       return hovered;
     });
  },[]);
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

UPDATED

For your case, I think you can use useRef to keep hovered data instead of a state.

const hoveredRef = React.useRef()

const onHover = useCallback((hovered) => {
   hoveredRef.current = hovered //won't make re-rendering
}, [])

const onClick = useCallback(() => {
   setSelectedData(hoveredRef.current)
}, [])

OLD ANSWER

<MemoChart
    {...{ data, onHover, onClick }}>
</MemoChart>

Your problem is these events onHover and onClick will be initialized newly every time which will cause unexpected renderings. If you have a complex computation on your component, it will be laggy on renderings.

In your onClick case with useCallback, it works but it will create more trouble in state handlers because it's lacking dependencies which means it's considering that function will be the same all the time, but in fact, your function is relying on hovered state should be changed on events.

I'd propose that you should pass dependencies to align with your used states in functions.

const onHover = useCallback((hovered) => {
   setHoveredItem(hovered);
}, []) //only initialize this function once after the component mounted

const onClick = useCallback(() => {
     setSelectedData(hovered);
},[hovered]); //initialize this function again when `hovered` state changes
about 4 years ago · Juan Pablo Isaza Relatório

0

const onClick = useCallback(() => {
     setHoveredItem((hovered)=>{
       setSelectedData(hovered);
       return hovered;
     });
  },[]);

This is not wrong, but it's a hack that helps you getting the fresh state if you have closures issues. In your case there is no reason since you are not working with closures, and the problem is just that you set an empty deps array. Now you say that this does not work:

const onClick = useCallback(() => {
       setSelectedData(hovered);
  },[hovered]);

But this MUST work, unless you are doing something wrong when you call setHovereditem.

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