React: O React Hook useEffect tem uma dependência ausente: 'xxx'?

Criado em 12 jun. 2019  ·  69Comentários  ·  Fonte: facebook/react

Olá, estou pesquisando o React Hook recentemente. É ótimo.

Mas estou com um problema, não encontrei uma resposta adequada na documentação do React Hook e no google para resolver meu problema.

Quando usei uma função em useEffect e o componente de função juntos, encontrei um aviso de que não especifiquei uma dependência em useEffect, conforme mostrado abaixo:

image

Existe alguma maneira de resolver meu problema? Eu pensei nisso por muito tempo.

Qual é o comportamento atual?

React Hook useEffect has a missing dependency: 'setCenterPosition'. Either include it or remove the dependency array. (react-hooks/exhaustive-deps)

Mini repro em codesandbox:
https://codesandbox.io/s/trusting-kowalevski-oet4b

Qualquer solução, obrigado.

Código

function App() {
  const [elePositionArr, setElePositionArr] = useState([
    { left: 0, top: 0 },
    { left: 0, top: 0 },
    { left: 0, top: 0 }
  ]);
  const stageRef = useRef(null);
  const Stage = useRef({ w: 0, h: 0 });
  const currentIndex = useRef(0);

  useEffect(() => {
    // Record the size of the stage
    const stageW = stageRef.current.scrollWidth;
    const stageH = stageRef.current.scrollHeight;

    Stage.current = { w: stageW, h: stageH };

    const index = Math.floor(Math.random() * 3);
    currentIndex.current = index;
    setCenterPosition(index);
  }, []);

  // Centering a block element
  function setCenterPosition(index) {
    let cacheEle = elePositionArr;
    // calc center postion
    const centerOfLeft = Stage.current.w / 2 - 25;
    const centerOfTop = Stage.current.h / 2 - 25;

    cacheEle = cacheEle.map((item, i) => {
      const randomWNum = Math.floor(Math.random() * Stage.current.w) - 50;
      const randomHNum = Math.floor(Math.random() * Stage.current.h) - 50;
      const randomLeft = randomWNum <= 50 ? 50 : randomWNum;
      const randomTop = randomHNum <= 50 ? 50 : randomHNum;
      let newItem;

      if (index === i) {
        newItem = { left: centerOfLeft, top: centerOfTop };
      } else {
        newItem = { left: randomLeft, top: randomTop };
      }

      return newItem;
    });

    setElePositionArr(cacheEle);
  }

  function handleClickLi(index) {
    if (currentIndex.current !== index) {
      setCenterPosition(index);
      currentIndex.current = index;
    }
  }

  return (
    <div className="container">
      <div className="stage" ref={stageRef}>
        {elePositionArr.map((item, index) => (
          <div className="ele" key={index} style={item}>
            {index}
          </div>
        ))}
      </div>
      <ul className="nav">
        {elePositionArr.map((item, index) => (
          <li
            className={currentIndex.current === index ? "active-li" : ""}
            onClick={() => {
              handleClickLi(index);
            }}
            key={"li" + index}
          >
            {index}
          </li>
        ))}
      </ul>
    </div>
  );
}

Comentários muito úteis

Quando milhares de desenvolvedores enfrentam o mesmo problema e a equipe de desenvolvimento do React fecha o tópico e ignora todos:
8d6

Todos 69 comentários

Isso deve responder à sua pergunta:

https://reactjs.org/docs/hooks-faq.html#is -it-safe-to-omit-functions-from-the-list-of-dependencies

Isso deve responder à sua pergunta:

https://reactjs.org/docs/hooks-faq.html#is -it-safe-to-omit-functions-from-the-list-of-dependencies

@gaearon
Não resolveu meu problema, meu problema é mais especial, meu run functionsetElePositionArr deseja disparar em componentDidMount e handleClick, mas a função React Hook não atende meus requisitos e um aviso aparece.

Minha pergunta é: React Hook não pode chamar uma função no componente useEffect e função para a operação setState?

Deixando em aberto para que possamos responder à segunda pergunta.

Estou tendo o mesmo aviso de ESLint, mas no meu caso quero fazer uma chamada assíncrona quando meu componente estiver montado.

const ManageTagsModalBody: React.FC<IProps> = ({ children, getTags }) => {
  useEffect(() => {
    getTags();
  }, []);

  return <div>{children}</div>;
};
Line 12:  React Hook useEffect has a missing dependency: 'getTags'. Either include it or remove the dependency array. If 'getTags' changes too often, find the parent component that defines it and wrap that definition in useCallback  react-hooks/exhaustive-deps 

ManageTagsModalBody não depende de nenhum dado, ele só é usado como um wrapper para carregar dados sempre que o componente é renderizado. É importante notar que o componente children está usando os dados que getTags tem busca.

Não tenho certeza do que adicionar à lista de dependências.

também estou interessado em uma explicação.
O React Hook useEffect tem uma dependência ausente: 'dispatch'.

  useEffect(() => {
    axios.get('http://localhost:8000/api/future-registrations')
      .then((result) => {
        dispatch(initRegistrationsAction(result.data));
      });
  }, []);

O mesmo problema aqui. Regra estranha.

Mesmo aqui. Tão simples quanto em https://github.com/facebook/react/issues/15865#issuecomment -506503377:

  useEffect(() => {
    dispatch(fetchPosts());
  }, []);

Existe uma maneira de suprimir esse aviso?

Conforme sugerido na mensagem de aviso, você pode fazer assim

const initFetch = useCallback(() => {
    dispatch(fetchPosts());
  }, [dispatch]);

  useEffect(() => {
    initFetch();
  }, [initFetch]);

@fayway então quando o valor de initFetch e dispatch for alterado, o callback de useEffect será executado.
ele quer executar o callback uma vez

@shkyung No meu caso, o initFetch não muda a causa (armazena.) o envio também não

Talvez possa ser assim

const setCenterPosition = useRef(null)
setCenterPosition.current = useCallback( ()=>{} ,[deps])

effect(()=>{ setCenterPosition.current() },[setCenterPosition,otherDeps])

Essa mudança parece um pouco ridícula e contraproducente, para ser franco. Em vez disso, volte para uma versão anterior e deixe você pensar sobre isso.

Tem o mesmo problema. Só quero que minha busca seja disparada em componentDidMount. Adicionar a dependência ao array resulta em atingir repetidamente o ponto de extremidade.

O React Hook useEffect tem uma dependência ausente: 'dispatch'.

const [state, dispatch] = useReducer(reducer, initialState);
const { count, step } = state;

useEffect(() => {
  const id = setInterval(() => {
    dispatch({ type: 'tick' }); // Instead of setCount(c => c + step);
  }, 1000);
  return () => clearInterval(id);
}, [dispatch]);

Este parece ser um caso de uso bastante comum - um que encontrei em meu projeto atual.

Você deseja executar um gancho de efeito apenas uma vez, mas HÁ uma dependência, embora você só se preocupe com o estado disso na inicialização. Atualmente usando
// eslint-disable-next-line react-hooks/exhaustive-deps ,
para desligar a regra de linting, mas seria bom não precisar nesse caso.

Este parece ser um caso de uso bastante comum - um que encontrei em meu projeto atual.

Você deseja executar um gancho de efeito apenas uma vez, mas HÁ uma dependência, embora você só se preocupe com o estado disso na inicialização. Atualmente usando
// eslint-disable-next-line react-hooks/exhaustive-deps ,
para desligar a regra de linting, mas seria bom não precisar nesse caso.

Fechar o Lint é apenas uma solução temporária, a chave para esse problema não é suficiente para entender o gancho.

O mesmo problema aqui. Eu só queria disparar uma função dentro de useEffect () uma vez, tendo [] como segundo parâmetro faz o que eu quero, mas continua dando este aviso.

Um aviso tão estranho porque nunca o vi antes até hoje em um novo projeto. Isso arruína o caso de uso de ter algo chamado apenas uma vez quando o componente é montado. Não parece haver nenhuma solução alternativa, exceto ignorar o aviso de fiapo.

Eu gostaria de colocar meus dois centavos aqui. Em particular com o uso do Axios para cancelar uma solicitação de rede. Criará um problema separado, se necessário, mas senti que esse problema afetou diretamente a mim mesmo. Portanto, meu gancho useApi é o seguinte -

import axios, { AxiosInstance } from "axios";
import axiosRetry from "axios-retry";
import { FetchEnv } from "../../utilities";
import { useStorage } from "../useStorage";

export const useApi = ({ isAuth = false, retries = 3 } = {}) => {
  const cancelToken = axios.CancelToken.source();
  const { getItem } = useStorage();

  const getBaseUrl = () => {
    return FetchEnv({
      defaultValue: "http://api.example.com",
      key: "API_URI"
    });
  };

  const authorizedClient = (client: AxiosInstance) => {
    const session = getItem("SESSION", "sessionStorage");
    const hasAccessToken = Boolean(session.tokens.accessToken);

    if (isAuth && !hasAccessToken) {
      console.error("No access token found to initiate authorized request.");
      return client;
    } else {
      client.defaults.headers[
        "Authorization"
      ] = `Bearer ${session.tokens.accessToken}`;
      return client;
    }
  };

  const buildFetch = (): AxiosInstance => {
    const client = axios.create({
      baseURL: getBaseUrl(),
      cancelToken: cancelToken.token
    });
    axiosRetry(client, { retries });
    return isAuth ? authorizedClient(client) : client;
  };

  return {
    cancelRequest: cancelToken.cancel,
    fetch: buildFetch()
  };
};

Para usar este gancho dentro de um componente, basta defini-lo conforme abaixo, então ele pode ser usado para fazer chamadas autenticadas e não autenticadas na montagem, dentro de um useEffect, como parte de um manipulador de eventos, etc. O cancelRequest é o token de cancelamento exclusivo gerado que está emparelhado com a instância axios "fetch" relativa a este componente.

const { cancelRequest, fetch } = useApi();

Se por algum motivo este componente desmontar, o seguinte é chamado:

  useEffect(() => {
    return () => {
      cancelRequest("Auth network request cancelled");
    };
  }, []);

Agora funciona perfeitamente no momento. No entanto, o aviso, quando aplicado (colocando cancelRequest como uma dependência useEffect) CANCELAM imediatamente a solicitação de rede quando o método fetch é chamado. Qualquer conselho seria muito apreciado, no entanto, parece que a única solução no momento seria ts-lint desabilitar isso daqui para frente ...

Acho que a questão aqui pode ser a maneira como pensamos sobre os ganchos. O comentário de @luojinghui sugere que há mais nisso do que

Me levou a pensar se, em @ 's exemplo logo acima disso, o código de tempo deve estar em um gancho useCallback? No entanto, ainda é estranho ter uma função (que deveria ser estática) como dependência.

Eu acho que este caso deveria ser algum tipo de exceção

Se você deseja executar uma função apenas uma vez quando o componente carrega e que aceita parâmetros, você pode usar useRef para evitar o aviso. Algo assim funciona:

  const InitialPropA= useRef(propA);
  useEffect(() => {
    myFunction(InitialPropA.current);
  }, [myFunction, InitialPropA]);

Conforme sugerido na mensagem de aviso, você pode fazer assim

const initFetch = useCallback(() => {
    dispatch(fetchPosts());
  }, [dispatch]);

  useEffect(() => {
    initFetch();
  }, [initFetch]);

Por mais que eu ame essa resposta inteligente, isso geralmente é o que acontece no meu código.
Não quero receber todos aqueles avisos incômodos sobre o desaparecimento de um despacho.

Eu adoraria saber exatamente o que e por que acontece nesse conjunto de mistérios :)

Conforme sugerido na mensagem de aviso, você pode fazer assim

const initFetch = useCallback(() => {
    dispatch(fetchPosts());
  }, [dispatch]);

  useEffect(() => {
    initFetch();
  }, [initFetch]);

isso também pode criar um vazamento de memória no caso de algo como uma API, ele fará a chamada em um loop infinito.

Realmente preciso de uma correção para isso. Ele continua me dando erros e nenhuma ideia de como resolvê-lo se você quiser disparar uma função dentro de useEffect() apenas uma vez.

Enfrentando o mesmo erro -

O React Hook useEffect tem uma dependência ausente: 'props'. No entanto, 'props' mudará quando qualquer prop mudar, então a solução preferida é desestruturar o objeto 'props' fora da chamada useEffect e referir-se a esses props específicos dentro de useEffect react-hooks / exaustive-deps

Código -

  useEffect(() => {
    props.dispatch(searchMediaAction("rain"));
  }, []);

@luojinghui : Deixe-me saber se você resolveu o erro de lint

mesmo erro

mesmo problema. Eu quero imitar o comportamento de componentDidMount; Não estou interessado no aviso; Eu não quero executar o gancho novamente quando algo mudar

Eu proporia não mostrar este aviso quando o segundo argumento para useEffect() for [] , b / c, nesse caso, o desenvolvedor sabe que este efeito só será executado uma vez e, portanto, _quer_deseja usar os valores iniciais do prop e não se importa se o prop muda nas renderizações subsequentes.

Caso 1:
Se quisermos que a função seja executada na inicialização, bem como quando os parâmetros especificados mudam de valor (como o aviso do lint sugere), passamos esses parâmetros para o array.

Caso 2:
Se quisermos que a função execute exatamente uma vez na inicialização , usamos um array vazio para que o efeito seja disparado apenas uma vez.

No Caso 2, estamos essencialmente ouvindo o evento componentDidMount de acordo com as especificações da documentação do React Hook. O erro de lint é inconsistente com a documentação do React Hook e com as expectativas do desenvolvedor.

Por que isso está fechado?

Alguma solução?

@kennylbj

Depois de tentar um monte de sugestões diferentes, isso é o que funcionou para mim. Eu preferi não usar eslint-disable, enquanto tento manter o código relativamente simples para um novato. Essa abordagem permite que você passe sua função de despacho sem invocá-la dentro de useCallback. Espero que isto ajude.

`` `javascript
// ... dentro do componente de função
const {dispatchFunc} = customHook ();
const memoizeDispatchFunc = useCallback (dispatchFunc, []);

useEffect (() => {
memoizeDispatchFunc ();
}, [memoizeDispatchFunc]);
`` ``

Podemos apenas remover o array vazio? Fazer isso parece funcionar (o código ainda roda conforme o esperado e o aviso desapareceu), mas não sei se há algum motivo para não fazermos dessa forma.

useEffect(()=>{ myFunc(); } )

@robthedev Greate solution.
Podemos até simplificar o código se usarmos redux:

const dispatch = useDispatch();

// redux can guarantee that the dispatch function will not change between renders.
// so we don't need to wrap it with useCallback for now.
useEffect(() => {
  dispatch(actions());
}, [dispatch]);

Este artigo do Dan me ajuda muito.

A solução para esse problema não é remover uma dependência, em vez disso, podemos içar funções que não precisam de props ou estado fora do componente ou envolvê-las em useCallback, onde estão definidas.

@kennylbj

Depois de tentar um monte de sugestões diferentes, isso é o que funcionou para mim. Eu preferi não usar eslint-disable, enquanto tento manter o código relativamente simples para um novato. Essa abordagem permite que você passe sua função de despacho sem invocá-la dentro de useCallback. Espero que isto ajude.

// ... inside function component
const { dispatchFunc } = customHook();
const memoizeDispatchFunc = useCallback(dispatchFunc, []);

useEffect(() => {
  memoizeDispatchFunc();
}, [memoizeDispatchFunc]);

Comigo, o exemplo acima não funciona.

Obtenha este erro:
TypeError: Cannot destructure property 'dispatchFunc' of 'componentDidMount(...)' as it is undefined.

@ react-team: Happy Boilerplate Code. :) Pode ser lógico e legível novamente ... os eventos devem ser simples de usar ... sem ter que escrever 5 ou mais linhas de lógica apenas para chamar uma função.

Para mim, o erro apareceu na seguinte situação:

  useEffect(() => {
    props.getTasks()
  }, [])

Eu corrigi assim:

const { getTasks } = props
  useEffect(() => {
    getTasks()
  }, [getTasks])

Quando milhares de desenvolvedores enfrentam o mesmo problema e a equipe de desenvolvimento do React fecha o tópico e ignora todos:
8d6

meu problema era diferente dos outros neste tópico, então vou compartilhá-lo no caso de qualquer outra pobre alma ir para a toca do coelho, eu só estive lá por 1 hora e meia

function hydrate( _state, _errors=false) {
    console.log('hydrate()');
    setState({...state,..._state});
    if(_errors){
        setErrors({...errors,..._errors});
    }
}

espera-se que o usuário use isso com useEffect() para hidratar seu estado da seguinte maneira:

useEffect(()=>{
    hydrate({
        name:'Garrett',
        email:'[email protected]',
        newsletter: 'yes'
    });
},[hydrate]); //unfortunately, this causes an infinite render, because hydrate will always change

então, para resolver isso, eu apenas mudei minha função de hidrato para ser envolvida em useCallback() , agora ela não é transformada em cada renderização (eu acho), e supostamente isso é melhor para o desempenho, o que se for verdade i irá implementar isso para todas as minhas funções auxiliares retornadas do meu gancho personalizado.

const hydrate = useCallback(( _state, _errors=false )=> {
    console.log('hydrate()');
    setState({...state,..._state});
    if(_errors){
        setErrors({...errors,..._errors});
    }
},[]);

Alguém pode confirmar se isso é verdade, useCallback está impedindo hydrate de sofrer mutação na renderização e, portanto, é provavelmente melhor envolver todas essas funções em useCallback para um melhor desempenho ?

redux can guarantee that the dispatch function will not change between renders.

Você tem certeza sobre isso?
Link para os documentos onde diz isso, por favor.

Verifique https://overreacted.io/a-complete-guide-to-useeffect/#decoupling -updates-from-actions para obter mais detalhes ou você pode verificar o código-fonte useEffect para obter detalhes de implementação.

Aqui, apenas faço referência ao que Dan disse:

A resposta é que o React garante que a função de despacho seja constante durante todo o tempo de vida do componente. Portanto, o exemplo acima nunca precisa reinscrever o intervalo.

garante que a função de despacho seja constante

Legal, obrigado!

Quando milhares de desenvolvedores enfrentam o mesmo problema e a equipe de desenvolvimento do React fecha o tópico e ignora todos:
8d6

Praticamente isso. Aqui estou eu experimentando os ganchos e sou saudado com este aviso que não faz sentido e não é abordado em nenhum dos documentos oficiais. Realmente faz você se perguntar se os ganchos estão prontos para um trabalho sério quando um caso de uso básico como "por favor, execute este efeito apenas uma vez" causa tantos problemas.

Bem, não há muito mais a dizer, tirando o fato de que o tópico está fechado smh.

Enfrenta o mesmo problema!

SOLUÇÃO,
(funcionou para mim):

const onInit = function(){ 
    console.log('initiated', Date.now());
}

useEffect(onInit, []);

Eu preferiria que o problema fosse corrigido no lado dos fiapos, mas hey ...

@ ra30r boa solução alternativa, mas está se perguntando se ela pode criar efeitos colaterais? :pensamento:

Nada ainda? 😔

Tive um caso em que aprendi a acionar erros de validação de formulário em um curso na Udemy.

Isso acionou a dependência ausente "dispatch", mas ainda funcionou:

  useEffect(() => {
    if (state.business_name.value) {
      const delay = setTimeout(() => dispatch({ type: "businessNameAfterDelay" }), 1000)
      return () => clearTimeout(delay)
    }
  }, [state.business_name.value])

Usando o exemplo de @ ra30r , mudei para este para limpar o erro:

  const businessNameAfterDelay = function () {
    if (state.business_name.value) {
      const delay = setTimeout(() => dispatch({ type: "businessNameAfterDelay" }), 1000)
      return () => clearTimeout(delay)
    }
  }

  useEffect(businessNameAfterDelay, [state.business_name.value])

Por que isso está fechado?

Eu acredito que uma resposta foi dada em algum lugar .. lol .. de qualquer maneira .. a solução é fazer assim:
useEffect(() => { dispatch(); }, [dispatch]);

espero que isto ajude!!

Por que isso está fechado?

Eu acredito que uma resposta foi dada em algum lugar .. lol .. de qualquer maneira .. a solução é fazer assim:
useEffect(() => { dispatch(); }, [dispatch]);

espero que isto ajude!!

Sim, essa solução alternativa funciona, @kennylbj disse aqui há algum tempo.
Por que o problema foi encerrado? Existem memes aqui também sobre isso ... xd

Meu problema é mais ou menos assim (código de amostra):

  const [userStatus, setUserStatus]: any = React.useState([]);
  const [userData, setUserData]: any = React.useState([]);

  useEffect(() => {
    setUserStatus(!userStatus);
    return () => {};
  }, [userData]);

Assim como no código, você deseja alterar o userStatus quando houver uma alteração em userData e, neste caso, se desejar verificar o userStatus você deve adicioná-lo aos deps:

  const [userStatus, setUserStatus]: any = React.useState([]);
  const [userData, setUserData]: any = React.useState([]);

  useEffect(() => {
    setUserStatus(!userStatus);
    return () => {};
  }, [userData, userStatus]);

neste cenário, será um loop sem fim

@spmsupun
Você pode usar o estilo de retorno de chamada de useState para evitar a introdução da variável userStatus na matriz de dependências de useEffect.

 useEffect(() => {
    setUserStatus(prevState => !prevState);
    return () => {};
  }, [userData]);

E isso é chamado de atualizações funcionais .

Solução -> basta adicionar despacho por último para dependência
O React Hook useEffect tem uma dependência ausente: 'dispatch'.

  useEffect(() => {
    axios.get('http://localhost:8000/api/future-registrations')
      .then((result) => {
        dispatch(initRegistrationsAction(result.data));
      });
**  }, [dispatch]);**

@kennylbj Isso é bom quando você lida com um estado, meu cenário real é com adereços. Estou enviando adereços do pai e ele muda duas vezes, então use as chamadas de efeito duas vezes, mas estou executando um ouvinte dentro dele e ele ouvirá duas vezes.

@spmsupun Mas acho que é bastante normal cancelar o registro do ouvinte anterior e registrar um novo ouvinte sempre que as variáveis ​​na matriz de dependências mudaram (por exemplo, quando o userId em props mudou, o ouvinte também precisou ser alterado). E esse comportamento é o que a reação espera ter.

Se você ainda não quiser que o ouvinte seja chamado duas vezes, acho que deve tomar mais cuidado com os adereços passados ​​para ele e ter certeza de que não será alterado durante as renderizações.

@kennylbj bem, eu
image
Acho que tenho que lidar com isso na classe de ouvinte,

Parece que o seu ouvinte é chamado duas vezes, mesmo que o id do soquete seja o mesmo.

Não acho que isso acontecerá se a seguinte situação se verificar:

ts // call useEffect if and only if sockeId changed. useEffect(() => { const unregister = register(socketId); return () => unregister(socketId); }, [socketId])

Há alguma outra variável na matriz de dependências alterada durante diferentes renderizações e causa esse comportamento?

Sim, 3 dependências, mas descobri de uma maneira diferente

Pien

Conforme sugerido na mensagem de aviso, você pode fazer assim

const initFetch = useCallback(() => {
    dispatch(fetchPosts());
  }, [dispatch]);

  useEffect(() => {
    initFetch();
  }, [initFetch]);

uau, 非常 感谢 你 🙏

🚀 O trecho de código abaixo funciona muito bem para mim

No componente foi montado

const onInit = () => getUsers()
useEffect(onInit, [])

Na mudança de parâmetro

const onInit = () => getUser(id)
useEffect(onInit, [id])

Melhor solução alternativa: react-hooks / exaustive-deps: "off"
Nunca achei esse recurso eslint útil. Sempre.

🚀 O trecho de código abaixo funciona muito bem para mim

No componente foi montado

const onInit = () => getUsers()
useEffect(onInit, [])

Na mudança de parâmetro

const onInit = () => getUser(id)
useEffect(onInit, [id])

bom trabalho.

Não acho que a documentação do react cubra @luojinghui , que também é o mesmo que eu:

Temos várias maneiras de chamar uma determinada função, ou seja: setCenterPosition() . Ele poderia ser chamado observando a mudança de estado (conectado via useEffect ), um manipulador de cliques (chamado diretamente), etc.

Os documentos de reação sugerem

É por isso que geralmente você deseja declarar funções necessárias para um efeito dentro dele

Mas geralmente em exemplos do mundo real, precisamos reutilizar funções como normalmente faríamos com métodos de instância em um componente de classe ( this.setCenterPosition(...) ), e estou começando a me perguntar se os ganchos são realmente bons para recursos completos, componentes complexos.

Não tenho certeza, mas talvez a solução seja useCallback

const setCenterPosition = useCallback(() => {
  ...
}, [Stage, elePositionArr, setElePositionArr]);

useEffect() => {
  ...
}, [stageRef, Stage, currentIndex, setCenterPosition]);

... mas isso é meio nojento para mim, e espero que haja uma maneira mais limpa. Talvez @gaearon possa confirmar?

enfrentando o mesmo problema, posso desativar o bu de aviso usando esta linha no final de useEffect // eslint-disable-next-line react-hooks/exhaustive-deps mas não quero usá-lo

Aqui está meu código

`const [items, setItems] = useState ([
{
nome: "teste 1",
id: 1
},
{
nome: "teste 2",
id: 2
},
{
nome: "teste 3",
id: 3
},
{
nome: "teste 4",
id: 4
},
{
nome: "teste 5",
id: 5
}
]);

useEffect (() => {
const intervalId = setInterval (() => {
setItems (shuffleArray (itens));
}, 1000);
return () => {
clearInterval (intervalId);
};
// eslint-disable-next-line react-hooks / exaustive-deps
}, []);

Minha solução para esse problema foi simplesmente parar de usar React Hooks para esses casos. Se o seu componente precisa de muita lógica de estado e eventos de ciclo de vida como componentDidMount tão mal, apenas use um componente de classe e evite a dor de cabeça. Os componentes de classe estão perfeitamente bem, e se este thread prova alguma coisa, é que os React Hooks não estão prontos para substituí-los totalmente quando a lógica de estado complexo ou eventos de ciclo de vida são necessários (nem eles conferem qualquer vantagem na maioria desses casos - seu código é _realmente_ muito melhor por ter usado React Hooks?).

Limitarei meu próprio uso de React Hooks a simples como useState para definir sinalizadores booleanos e esse tipo de coisa. Se um componente ficar complexo o suficiente para precisar de useEffect eu trato isso como um sinal de que talvez um componente de classe seja apenas um ajuste melhor.

(Editado para maior clareza).

Esta é a minha solução por enquanto:

const mounted = () => {
  dispatch(something());
}

useEffect(mounted, []);

Obrigado @ ra30r react / issues / 15865 # issuecomment-651254164

Esta página foi útil?
0 / 5 - 0 avaliações