React.useState no recarga el estado de los accesorios

95

Espero que el estado se recargue en el cambio de accesorios, pero esto no funciona y la uservariable no se actualiza en la próxima useStatellamada, ¿qué está mal?

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});
  return user.avatar ? 
         (<img src={user.avatar}/>)
        : (<p>Loading...</p>);
}

codepen

vitalyster
fuente

Respuestas:

210

El argumento pasado a useState es el estado inicial muy parecido al estado de configuración en el constructor para un componente de clase y no se usa para actualizar el estado al volver a renderizar

Si desea actualizar el estado en el cambio de prop, use el useEffectgancho

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});

  React.useEffect(() => {
      setUser(props.user);
  }, [props.user])

  return user.avatar ? 
         (<img src={user.avatar}/>)
        : (<p>Loading...</p>);
}

Demo de trabajo

Shubham Khatri
fuente
18
Al establecer el estado inicial en el constructor, es claro entender que se llama al constructor una vez en la creación de la instancia de clase. Con los ganchos, parece que se llama a useState cada vez que se llama a la función y cada vez que debe inicializar el estado, pero allí ocurre algo de "magia" inexplicable.
vitalyster
Tal vez esta publicación arroje algo de luz sobre ella stackoverflow.com/questions/54673188/…
Shubham Khatri
si necesita fusionar accesorios en el estado, se queda atascado en un bucle infinito cuando usa create-react-app que requiere que el estado esté en la matriz de dependencia
user210757
2
Esto termina configurando el estado inicial dos veces, lo cual es bastante molesto. Me pregunto si puede establecer el estado inicial en nulo y luego usarlo React.useEffectpara establecer el estado inicial en cada momento.
CMCDragonkai
2
Esto no funciona si el estado también controla el renderizado. Tengo un componente funcional que se renderiza basándose en accesorios y renderiza según el estado. Si el estado le dice al componente que se procese porque cambió, useEffect se ejecuta y establece el estado de nuevo en el valor predeterminado. Este es un diseño realmente malo de su parte.
Greg Veres
1

Componentes funcionales donde usamos useStatepara establecer valores iniciales para nuestra variable, si pasamos el valor inicial a través de accesorios, siempre establecerá el mismo valor inicial hasta que no haga uso del useEffectgancho,

por ejemplo su caso esto hará su trabajo

 React.useEffect(() => {
      setUser(props.user);
  }, [props.user])

La función pasada a useEffect se ejecutará después de que el renderizado se confirme en la pantalla.

De forma predeterminada, los efectos se ejecutan después de cada renderizado completo, pero puede optar por activarlos solo cuando ciertos valores hayan cambiado.

React.useEffect(FunctionYouWantToRunAfterEveryRender)

si pasa solo un argumento a useEffect, ejecutará este método después de cada renderizado, puede decidir cuándo activar esto FunctionYouWantToRunAfterEveryRenderpasando el segundo argumento a useEffect

React.useEffect(FunctionYouWantToRunAfterEveryRender, [props.user])

como notará, estoy pasando [props.user] ahora useEffectsolo activará esta FunctionYouWantToRunAfterEveryRenderfunción cuando props.userse cambie

Espero que esto ayude a su comprensión, avíseme si se requieren mejoras gracias

Hanzla Habib
fuente
0

El parámetro pasado React.useState()es solo el valor inicial para ese estado. React no reconocerá eso como un cambio de estado, solo configurando su valor predeterminado. Querrá establecer el estado predeterminado inicialmente y luego llamar condicionalmente setUser(newValue), que se reconocerá como un nuevo estado, y volver a renderizar el componente.

Recomendaría tener cuidado al actualizar el estado sin algún tipo de condición para evitar que se actualice constantemente y, por lo tanto, vuelva a renderizar cada vez que se reciban los accesorios. Es posible que desee considerar elevar la funcionalidad de estado a un componente principal y pasar el estado del padre a este Avatar como accesorio.

Soñoliento
fuente
-2

Según la documentación de ReactJS sobre Hooks :

Pero, ¿qué sucede si el accesorio de amigo cambia mientras el componente está en la pantalla? Nuestro componente continuaría mostrando el estado en línea de un amigo diferente. Esto es un error. También causaríamos una pérdida de memoria o un bloqueo al desmontar, ya que la llamada para cancelar la suscripción usaría la identificación de amigo incorrecta.

Su única interacción aquí debería ocurrir en un cambio de accesorios, que parece no funcionar. Podría (aún de acuerdo con el documento) usar un componentDidUpdate (prevProps) para detectar de manera proactiva cualquier actualización de los accesorios.

PD: No tengo suficiente código para juzgar, pero ¿no podrías establecer activamente Usuario () dentro de tu función Avatar (accesorios)?

Mwak
fuente
-12

En el mundo de reacción, debe actualizar su estado en la función componentWillRecieveProps (nextProps), en tales casos.

Sushil Mahajan
fuente
4
Lo que ya no es cierto para las últimas versiones de react
Shubham Khatri