Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create useDeepCompareCallback #2615

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

pedromtec
Copy link
Contributor

@pedromtec pedromtec commented Jan 13, 2025

What's the purpose of this pull request?

Possível fix para a duplicação do evento view_cart. Quando tentamos abrir o carrinho o evento é disparado mais de uma vez.

O problema parece está nessa linha . Usar objetos e arrays como dependência de useCallback, useEffect, etc pode fazer com o que código seja executado mais de uma vez. Isso porque o React utiliza o método Object.is para fazer comparações dos itens do array de dependência. Podem testar esse caso:
Percebam que são arrays "iguais", porém com referência na memória diferente.

const products1 = ['apple','iphone']
const products2 = ['apple','iphone']
console.log(Object.is(products1, products2)) // output = false

No nosso caso temos o gifts e items que são arrays. Em algum momento essas estados estão chegando com uma referência diferente, consequentemente disparando a lógica da função novamente.

A solução proposta é fazer um deep compare no array de dependencias, usando JSON.stringify. Essa abordagem é mais robusta, mas pode ser computacionalmente cara dependendo do tamanho dos items que serão comparados.

Essa é apenas uma solução para ser discutida e testada, não é um PR final. Alguns ajustes precisam ser feitos no código caso a gente continue nessa abordagem.

How it works?


function useDeepCompareCallback<T extends Function>(
  callback: T,
  dependencies: DependencyList
): T {
  const previousDeps = useRef<DependencyList>()

  const isEqual = (a: unknown, b: unknown) =>
    JSON.stringify(a) === JSON.stringify(b)

  if (!isEqual(previousDeps.current, dependencies)) {
    previousDeps.current = dependencies
  }

  // eslint-disable-next-line react-hooks/exhaustive-deps
  return useCallback(callback, previousDeps.current)
}

How to test it?

Starters Deploy Preview

References

Checklist

You may erase this after checking them all 😉

PR Title and Commit Messages

  • PR title and commit messages follow the Conventional Commits specification
    • Available prefixes: feat, fix, chore, docs, style, refactor, ci and test

PR Description

  • Added a label according to the PR goal - breaking change, bug, contributing, performance, documentation..

Dependencies

  • Committed the yarn.lock file when there were changes to the packages

Documentation

  • PR description
  • For documentation changes, ping @Mariana-Caetano to review and update (Or submit a doc request)

Copy link

vercel bot commented Jan 13, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
faststore-site ✅ Ready (Inspect) Visit Preview Jan 13, 2025 7:07pm

Copy link

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant