React: ganchos: useContext con useState no se actualiza

Creado en 26 ene. 2019  ·  3Comentarios  ·  Fuente: facebook/react

¿Quieres solicitar una función o informar de un error ?

parece que es un error . 😕

¿Cuál es el comportamiento actual?

El proveedor de contexto anidado y los ganchos useContext parecen estar en conflicto, las actualizaciones se descartan.

¿Cuál es el comportamiento esperado?

Al conectarse a un contexto, debería actualizarse cada vez que cambie value .

¿Qué versiones de React y qué navegador / sistema operativo se ven afectados por este problema?

  • reaccionar : 18.8.0-alpha.1 (también reproducido en 16.7.0-alpha.0 )
  • navegador : chrome 71
  • sistema operativo : macOS Sierra

más detalles

Mientras trabaja en la limpieza de una "conexión" localStorage,
Intenté mezclar 2 artículos ( [1] & [2] ) de la documentación oficial de reacción, lo implementé con ganchos, pero el valor parece no pasar.

He puesto una demostración simplificada en codesandbox [3] .

La implementación real es solo un par de líneas más (analizándola y asignándola a JSON).

Soluciones alternativas que encontré:

  • Si creo una nueva función en cada render alrededor de la función setValue , realmente funciona.

    • pero esto va en contra del consejo de [1] sobre evitar la creación de nuevos valores.

  • Mírelo a una clase y use componentDidUpdate lugar de useEffect .

    • De hecho, estoy usando esto ahora mismo, ya que funciona. Incluido guardar una referencia a la función en el estado.


¿Hay algo que no debería funcionar en el siguiente código? el efecto se activa con los cambios,
pero el valor no se actualiza en los componentes que consumen a través de hook. ver código de reproducción [3]

const createLocalStorage = key => {
    const initialValue = localStorage.getItem(key)
    const ValueContext = createContext(initialValue)
    const SetterContext = createContext(() => {})

    const useStorage = () => [ValueContext, SetterContext].map(useContext)

    const Provider = ({children}) => {
        const [value, setValue] = useState(initialValue)

        useEffect(
            () => {
                console.log('effect', value)
                localStorage.setItem(key, value)
            },
            [value],
        )

        return (
            <ValueContext.Provider value={value}>
                <SetterContext.Provider value={setValue}>
                    {children}
                </SetterContext.Provider>
            </ValueContext.Provider>
        )
    }

    return [Provider, useStorage]
}

[1] : https://reactjs.org/docs/hooks-faq.html#how -to-evitar-pasar-callbacks-down
[2] : https://reactjs.org/docs/context.html#updating -context-from-a-nested-component
[3] : https://codesandbox.io/s/0yzjr8vnrv


hlcecpq

Question

Comentario más útil

He puesto una demostración simplificada en codesandbox [3].

Me parece que sus llamadas useContext están en el mismo componente que Provider . En ese sentido, están leyendo el contexto por encima del Proveedor (el predeterminado).

El valor del proveedor solo influye en el contexto de los componentes dentro de él.

Por cierto, si no intentaste engañar a las reglas de Hooks con un código como [A, B].map(useContext) es posible que lo hayas notado antes ;-)

Todos 3 comentarios

He puesto una demostración simplificada en codesandbox [3].

Me parece que sus llamadas useContext están en el mismo componente que Provider . En ese sentido, están leyendo el contexto por encima del Proveedor (el predeterminado).

El valor del proveedor solo influye en el contexto de los componentes dentro de él.

Por cierto, si no intentaste engañar a las reglas de Hooks con un código como [A, B].map(useContext) es posible que lo hayas notado antes ;-)

¡Hola Dan! gracias por la respuesta rápida (: lo arreglé por mí.

por cierto: useContext (a través de useStorage ) está dentro de App , que _ está_ dentro de Provider en la función ReactDOM.render . (tal vez hice el ejemplo demasiado corto para ver este anidamiento).


solucion :

Lo resolví modificando esa peculiar línea .map : me perdí el parámetro observedBits , que terminó siendo transmitido. Lo leí aquí en los problemas / relaciones públicas, pero lo olvidé. al implementarlo, y terminó alterando el comportamiento.

Aaah tienes razón, leí mal tu ejemplo. Sí, observedBits es el problema aquí. Parece una trampa, pero tampoco recomendamos llamar a useContext dinámicamente, así que ...

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