Eu tenho uma windowSize de dependências. Eu também tenho um campo de entrada de pesquisa onde eu atualizo o estado de pesquisa. Se eu der uma dica em meu estado de pesquisa, meus sites são renderizados novamente, é claro, porque eu atualizo um estado. Mas eu tenho uma função encapsulada em useCallback, mas o problema é que ela é acionada. Então, por que ela é acionada? Ela só deve ser acionada quando a windowSize de dependência/estado for alterada.
const [searchValue, setSearchValue] = useState<string>('');
useEffect(() => {
gridRef.current?.recomputeGridSize();
console.log('TRIGGER WINDOW SIZE')
}, [windowSize]);
const calculateColumnCount = useCallback((width: number) => {
console.log('CALLBACK FUNC')
return Math.floor(width / itemMinWidth);
}, [windowSize])
const columnCount = numColumns ?? calculateColumnCount(containerWidth);
Coloquei apenas as coisas importantes no snipped. Se quiser, posso compartilhar o código completo.
o que estou fazendo errado?
Sua função é acionada devido a:
Quando você faz useCallback, ele criaria uma função que obtém
recreated
se a dependência de useCallback for alterada. Quando especificado assim em um corpo de componente,columnCount
seria chamado a cada nova renderização.Se você quiser evitar uma chamada, você tem que usar o Memorando:
Uma coisa a ter em mente é que o
useCallback
hook não impede a invocação, ele garante que as referências de função permaneçam estáveis entre as renderizações, desde que suas dependências (windowSize
no seu caso) não mudem.esta linha
executa sempre que
numColumns
for falso. Esta execução é independente de auseCallback
referência ter sido alterada.O segundo ponto a ter em mente é
Mudanças de estado causam re-renderizações. Quando você atualiza o
searchValue
estado digitando no campo de entrada de pesquisa, isso causa uma re-renderização do componente. Durante a re-renderização, senumColumns
for falso, acalculateColumnCount
função é invocada novamente.https://react.dev/learn/updating-objects-in-state
Então, se sua intenção é chamar uma função apenas uma vez, tenha uma
useEffect
função com um array de dependências vazio (está tudo bem mesmo se o compilador gerar um pequeno warring).Caso esta solução não o satisfaça, você também pode usar o
useMemo
ganchoOu considere usar o react redux toolkit que ajudará você a gerenciar o estado de forma eficaz. Sua curva de aprendizado pode ser rígida, mas eu realmente recomendo :)
continue programando, cara, e divirta-se :)