React: React Hook useEffect tiene una dependencia faltante: 'xxx'?

Creado en 12 jun. 2019  ·  69Comentarios  ·  Fuente: facebook/react

Hola, estoy investigando React Hook recientemente, es genial.

Pero tengo un problema, no encontré una respuesta adecuada en la documentación de React Hook y google para resolver mi problema.

Cuando usé una función en useEffect y un componente de función juntos, encontré una advertencia de que no especifiqué una dependencia en useEffect, como se muestra a continuación:

image

¿Existe alguna forma de solucionar mi problema? Lo he pensado durante mucho tiempo.

¿Cuál es el comportamiento actual?

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

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

Cualquier solución, gracias.

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>
  );
}

Comentario más útil

Cuando miles de desarrolladores enfrentan este mismo problema y el equipo de desarrollo de React cierra el hilo e ignora a todos:
8d6

Todos 69 comentarios

Esto debería responder a tu pregunta:

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

Esto debería responder a tu pregunta:

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

@gaearon
No resolvió mi problema, mi problema es más especial, mi función de ejecuciónsetElePositionArr quiere disparar en componentDidMount y handleClick, pero la función React Hook no cumple con mis requisitos y aparece una advertencia.

Mi pregunta es: React Hook no puede llamar a una función en el componente useEffect y function para la operación setState?

Dejándolo abierto para que podamos responder a la segunda pregunta.

Tengo la misma advertencia de ESLint, pero en mi caso quiero hacer una llamada asíncrona cuando mi componente está 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 no depende de ningún dato, solo se usa como contenedor para cargar datos cada vez que se procesa el componente. Vale la pena señalar que el componente children está usando los datos que getTags ha obtenido.

No estoy seguro de qué agregar a la lista de dependencias.

También estoy interesado en una explicación.
React Hook useEffect tiene una dependencia faltante: 'despacho'.

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

El mismo problema aquí. Regla extraña.

Aquí igual. Tan simple como en https://github.com/facebook/react/issues/15865#issuecomment -506503377:

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

¿Hay alguna forma de suprimir esta advertencia?

Como se sugiere en el mensaje de advertencia, puede hacer eso

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

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

@fayway, cuando se modifiquen initFetch y el valor de envío, se ejecutará la devolución de llamada de useEffect.
quiere ejecutar la devolución de llamada una vez

@shkyung En mi caso, initFetch no cambiará la causa (almacenar) el envío tampoco

Tal vez pueda ser así

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

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

Este cambio parece un poco ridículo y contraproducente para ser franco. En su lugar, retroceda a una versión anterior y déjele pensar en esta.

Tiene el mismo problema. Solo quiero que mi recuperación se active en componentDidMount. Agregar la dependencia a la matriz da como resultado que se alcance repetidamente el punto final.

React Hook useEffect tiene una dependencia faltante: 'despacho'.

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 un caso de uso bastante común, uno con el que me he encontrado en mi proyecto actual.

Desea ejecutar un gancho de efecto solo una vez, pero hay una dependencia, aunque solo le importa el estado de eso al inicio. Actualmente usando
// eslint-disable-next-line react-hooks/exhaustive-deps ,
para desactivar la regla de pelusa, pero sería bueno no tener que hacerlo en este caso.

Este parece ser un caso de uso bastante común, uno con el que me he encontrado en mi proyecto actual.

Desea ejecutar un gancho de efecto solo una vez, pero hay una dependencia, aunque solo le importa el estado de eso al inicio. Actualmente usando
// eslint-disable-next-line react-hooks/exhaustive-deps ,
para desactivar la regla de pelusa, pero sería bueno no tener que hacerlo en este caso.

Cerrar Lint es solo una solución temporal, la clave de este problema no es suficiente para entender el gancho.

El mismo problema aquí. Solo quería disparar una función dentro de useEffect () una vez, tener [] como segundo parámetro hace lo que quiero, pero sigue dando esta advertencia.

Una advertencia tan extraña porque nunca la había visto antes hasta hoy en un nuevo proyecto. Arruina el caso de uso de tener algo llamado solo una vez cuando el componente se ha montado. No parece haber ninguna solución alternativa, excepto ignorar la advertencia de pelusa.

Me gustaría poner mis dos centavos aquí. En particular con el uso de Axios para cancelar una solicitud de red. Crearé un problema separado si es necesario, pero sentí que este problema me afectó directamente. Entonces mi gancho useApi es el siguiente:

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 un componente, simplemente defínalo como se muestra a continuación, luego se puede usar para realizar llamadas tanto autenticadas como no autenticadas, ya sea en el montaje, dentro de un useEffect, como parte de un controlador de eventos, etc. El cancelRequest es el token de cancelación único generado que está emparejado con la instancia de axios "fetch" relativa a este componente.

const { cancelRequest, fetch } = useApi();

Si por alguna razón este componente se desmonta, se llama a lo siguiente:

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

Ahora funciona perfectamente en la actualidad. Sin embargo, la advertencia, cuando se aplica (poniendo cancelRequest como una dependencia useEffect) CANCELA inmediatamente la solicitud de red cuando se llama al método de recuperación. Cualquier consejo sería muy apreciado, sin embargo, parece que la única solución en este momento sería desactivar ts-lint para seguir adelante ...

Creo que el problema aquí puede ser la forma en que pensamos sobre los ganchos. El comentario de @luojinghui sugiere que hay más en esto de lo que parece. ¿Quizás necesitamos pensar de manera diferente? He podido eliminar este problema en uno de mis ganchos con un poco de refactorización. El código es más claro como resultado.

Me llevó a preguntarme si, en el ejemplo de @ Stoner609 justo encima de esto, el código de tiempo debería estar en un gancho useCallback. Sin embargo, sigue siendo extraño tener una función (que debería ser estática) como dependencia.

Creo que este caso debería ser una excepción.

Si desea ejecutar una función solo una vez cuando el componente se carga y que toma parámetros, puede usar useRef para evitar la advertencia. Algo como esto funciona:

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

Como se sugiere en el mensaje de advertencia, puede hacer eso

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

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

Por mucho que me guste esta ingeniosa respuesta, esto suele ser lo que sucede en mi código.
No quiero tener todas esas molestas advertencias sobre la desaparición del envío.

Me encantaría saber exactamente qué y por qué sucede en ese conjunto de misterio :)

Como se sugiere en el mensaje de advertencia, puede hacer eso

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

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

esto también puede crear una pérdida de memoria en caso de algo como una API, hará la llamada en un bucle infinito.

Realmente necesito una solución para esto. Sigue dándome errores y no tengo ideas de cómo resolverlo si desea activar una función dentro de useEffect() solo una vez.

Frente al mismo error -

React Hook useEffect tiene una dependencia faltante: 'props'. Sin embargo, 'props' cambiará cuando cambie cualquier prop, por lo que la solución preferida es desestructurar el objeto 'props' fuera de la llamada useEffect y hacer referencia a esos props específicos dentro de useEffect react-hooks / exhaustive-deps

Código -

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

@luojinghui : Avíseme si resolvió el error de pelusa

mismo error

el mismo problema. Quiero imitar el comportamiento de componentDidMount; No me interesa la advertencia; No quiero volver a ejecutar el gancho cuando algo cambia

Propondría no mostrar esta advertencia cuando el segundo argumento de useEffect() es [] , b / c, en ese caso, el desarrollador sabe que este efecto solo se ejecutará una vez y, por lo tanto, _quiere_ usar los valores de prop inicial y no le importa si el prop cambia en renders posteriores.

Caso 1:
Si queremos que la función se ejecute en la inicialización, así como cuando los parámetros especificados cambian de valor (como sugiere la advertencia de lint), entonces pasamos esos parámetros a la matriz.

Caso 2:
Si queremos que la función se ejecute exactamente una vez en la inicialización , usamos una matriz vacía para que el efecto solo se active una vez.

En el caso 2, esencialmente estamos escuchando el evento componentDidMount de acuerdo con las especificaciones de la documentación de React Hook. El error de pelusa es inconsistente con la documentación de React Hook y las expectativas de los desarrolladores.

¿Por qué esta cerrado?

¿Alguna solución?

@kennylbj

Después de probar un montón de sugerencias diferentes, esto es lo que finalmente funcionó para mí. Preferí no usar eslint-disable, mientras trataba de mantener el código relativamente simple para un novato. Este enfoque le permite pasar su función de envío sin invocarla dentro de useCallback. Espero que esto ayude.

`` `javascript
// ... dentro del componente de la función
const {dispatchFunc} = customHook ();
const memoizeDispatchFunc = useCallback (dispatchFunc, []);

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

¿Podemos simplemente eliminar la matriz vacía? Hacerlo parece funcionar (el código aún se ejecuta como se esperaba y la advertencia desaparece), pero no sé si hay alguna razón por la que no deberíamos hacerlo de esa manera.

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

@robthedev Gran solución.
Incluso podemos simplificar el código si usamos 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]);

Dan, este artículo me ayuda mucho.

La solución a este problema no es eliminar una dependencia, en su lugar, podemos izar funciones que no necesitan accesorios o estado fuera del componente o envolverlas en useCallback donde están definidas.

@kennylbj

Después de probar un montón de sugerencias diferentes, esto es lo que finalmente funcionó para mí. Preferí no usar eslint-disable, mientras trataba de mantener el código relativamente simple para un novato. Este enfoque le permite pasar su función de envío sin invocarla dentro de useCallback. Espero que esto ayude.

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

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

En mi caso, el ejemplo anterior no funciona.

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

@ react-team: Happy Boilerplate Code. :) ¿Puede ser lógico y legible de nuevo ... los eventos deben ser fáciles de usar ... sin tener que escribir más de 5 líneas de lógica solo para llamar a una función?

Para mí, el error apareció en la siguiente situación:

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

Lo corregí así:

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

Cuando miles de desarrolladores enfrentan este mismo problema y el equipo de desarrollo de React cierra el hilo e ignora a todos:
8d6

mi problema fue diferente a otros en este hilo, así que lo compartiré en caso de que cualquier otra pobrecita se vaya por la madriguera del conejo. Acabo de estar abajo durante 1 1/2 horas.

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

se espera que el usuario use esto con useEffect() para hidratar su estado así:

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

así que para resolver esto, acabo de cambiar mi función de hidratación para que esté envuelta en useCallback() , ahora no está mutado en cada renderizado (supongo), y supuestamente esto es mejor para el rendimiento, que si eso resulta ser cierto i implementará esto para todas mis funciones auxiliares devueltas desde mi gancho personalizado.

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

¿Alguien puede confirmar si esto es cierto, useCallback está evitando que hydrate se mute en el renderizado, y por lo tanto, probablemente sea mejor envolver todas estas funciones en useCallback para un mejor rendimiento? ?

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

¿Estás seguro de eso?
Enlace a los documentos donde lo indique, por favor.

Consulte https://overreacted.io/a-complete-guide-to-useeffect/#decoupling -updates-from-actions para obtener más detalles o puede consultar el código fuente de useEffect para obtener detalles de implementación.

Aquí solo hago referencia a lo que dijo Dan:

La respuesta es que React garantiza que la función de envío sea constante durante toda la vida útil del componente. Por lo tanto, el ejemplo anterior no necesita volver a suscribirse al intervalo.

garantiza que la función de envío sea constante

¡Genial, gracias!

Cuando miles de desarrolladores enfrentan este mismo problema y el equipo de desarrollo de React cierra el hilo e ignora a todos:
8d6

Bastante esto. Aquí estoy probando los ganchos y me saludan con esta advertencia que no tiene sentido y no está cubierta en ninguno de los documentos oficiales. Realmente te hace preguntarte si los ganchos están listos para un trabajo serio cuando un caso de uso básico como "por favor, ejecuta este efecto solo una vez" da tantos problemas.

Bueno, no hay mucho más que decir, aparte del hecho de que el hilo está cerrado smh.

¡Se enfrenta al mismo problema!

SOLUCIÓN,
(que funcionó para mí):

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

useEffect(onInit, []);

Preferiría que el problema se solucione en el lado de la pelusa, pero bueno ...

@ ra30r es una buena solución, pero se pregunta si puede crear efectos secundarios. :pensando:

¿Todavía nada? 😔

Tuve un caso en el que aprendí a activar errores de validación de formularios en un curso en Udemy.

Esto desencadenó el "envío" de dependencia faltante, pero aún funcionó:

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

Usando el ejemplo de @ ra30r , lo cambié a esto para borrar el error:

  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 qué esta cerrado?

Creo que se ha dado una respuesta en alguna parte ... jajaja ... de todos modos ... la solución es hacer así:
useEffect(() => { dispatch(); }, [dispatch]);

¡¡espero que esto ayude!!

¿Por qué esta cerrado?

Creo que se ha dado una respuesta en alguna parte ... jajaja ... de todos modos ... la solución es hacer así:
useEffect(() => { dispatch(); }, [dispatch]);

¡¡espero que esto ayude!!

Sí, esa solución funciona, dijo @kennylbj aquí hace algún tiempo.
¿Por qué el problema está cerrado? Hay memes aquí también sobre eso ... xd

Mi problema es un poco como este (código de muestra):

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

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

Entonces, como en el código, desea cambiar el userStatus cuando hay un cambio en userData y, en este caso, si desea verificar el userStatus , debe agregarlo a los deps:

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

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

en este escenario será un bucle sin fin

@spmsupun
Puede usar el estilo de devolución de llamada de useState para evitar introducir la variable userStatus en la matriz de dependencias de useEffect.

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

Y esto se llama actualizaciones funcionales .

Solución -> simplemente agregue el envío en último lugar para la dependencia
React Hook useEffect tiene una dependencia faltante: 'despacho'.

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

@kennylbj Esto es bueno cuando se trata de un estado, mi escenario real es con accesorios. Estoy enviando un accesorio de los padres y cambia dos veces, así que usereffect llama dos veces, pero estoy ejecutando un oyente dentro de él y escuchará dos veces.

@spmsupun Pero creo que es bastante normal anular el registro del oyente anterior y registrar un nuevo oyente cada vez que cambiaban las variables en la matriz de dependencias (por ejemplo, cuando cambiaba el ID de usuario en los accesorios, también era necesario cambiar el oyente). Y este comportamiento es el que espera reaccionar.

Si aún no desea hacer que el oyente sea llamado dos veces, creo que debería tener más cuidado con los accesorios que se le pasan y asegurarse de que no se modifiquen durante los renderizados.

@kennylbj bueno,
image
Supongo que tengo que manejar esto desde la clase de escucha,

Parece que se llama dos veces a su oyente incluso si la identificación del socket es la misma.

No creo que esto suceda si se da la siguiente situación:

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

¿Hay otras variables en la matriz de dependencias cambiadas durante diferentes representaciones y causan este comportamiento?

Sí, 3 dependencias, pero lo averiguo de una manera diferente.

Pien

Como se sugiere en el mensaje de advertencia, puede hacer eso

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

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

wow , 非常 感谢 你 🙏

🚀 El siguiente fragmento de código funciona muy bien para mí

En el componente se montó

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

En cambio de parámetro

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

Mejor solución alternativa: react-hooks / exhaustive-deps: "off"
Nunca he encontrado que esta función de eslint sea útil. Siempre.

🚀 El siguiente fragmento de código funciona muy bien para mí

En el componente se montó

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

En cambio de parámetro

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

Buen trabajo.

No creo que los documentos de reacción cubran bastante el caso de uso de @luojinghui , que también es el mismo que tengo:

Tenemos varias formas de llamar a una función determinada, es decir: setCenterPosition() . Se puede llamar observando el cambio de estado (conectado a través de useEffect ), un controlador de clic (llamado directamente), etc.

Los documentos de reacción sugieren

Esta es la razón por la que generalmente querrá declarar las funciones necesarias para un efecto dentro de él.

Pero generalmente en ejemplos del mundo real, necesitamos reutilizar funciones como lo haríamos normalmente con métodos de instancia en un componente de clase ( this.setCenterPosition(...) ), y estoy empezando a preguntarme si los ganchos son realmente buenos para funciones completas, componentes complejos.

En realidad no estoy seguro, pero tal vez la solución sea useCallback

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

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

... pero eso es un poco asqueroso para mí, y espero que haya una manera más limpia. ¿Quizás @gaearon pueda confirmarlo?

frente al mismo problema, puedo deshabilitar la advertencia pero usando esta línea al final de useEffect // eslint-disable-next-line react-hooks/exhaustive-deps pero no quiero usarlo

Aquí está mi código

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

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

Mi solución a este problema ha sido simplemente dejar de usar React Hooks para estos casos. Si su componente necesita mucha lógica de estado y eventos de ciclo de vida como componentDidMount tan mal, simplemente use un componente de clase y ahórrese el dolor de cabeza. Los componentes de clase están perfectamente bien, y si este hilo prueba algo, es que los React Hooks no están listos para reemplazarlos por completo cuando se necesitan eventos de ciclo de vida o lógica de estado compleja (ni confieren ninguna ventaja en la mayoría de estos casos, es su código _realmente_ ¿Mucho mejor por haber usado React Hooks?).

Limitaré mi propio uso de React Hooks a simples como useState para establecer indicadores booleanos y ese tipo de cosas. Si un componente alguna vez se vuelve lo suficientemente complejo como para necesitar useEffect lo trato como una señal de que tal vez un componente de clase se ajusta mejor.

(Editado para mayor claridad).

Esta es mi solución por ahora:

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

useEffect(mounted, []);

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

¿Fue útil esta página
0 / 5 - 0 calificaciones