React: hooks: useContext dengan useState tidak memperbarui

Dibuat pada 26 Jan 2019  ·  3Komentar  ·  Sumber: facebook/react

Apakah Anda ingin meminta fitur atau melaporkan bug ?

Sepertinya itu bug . 😕

Bagaimana perilaku saat ini?

Penyedia konteks bersarang dan useContext hooks tampaknya berkonflik, pembaruan akan dibuang.

Apa perilaku yang diharapkan?

Saat menghubungkan ke konteks, itu harus diperbarui setiap kali value berubah.

Versi React mana, dan browser / OS mana yang terpengaruh oleh masalah ini?

  • react : 18.8.0-alpha.1 (juga direproduksi pada 16.7.0-alpha.0 )
  • browser : chrome 71
  • os : macOS Sierra

keterangan lebih lanjut

Saat mengerjakan pembersihan "koneksi" localStorage,
Saya mencoba mencampur 2 artikel ( [1] & [2] ) dari dokumentasi react resmi, saya telah menerapkannya dengan kait, tetapi nilainya tampaknya tidak lewat.

Saya telah membuat demo yang efisien di Codesandbox [3] .

Implementasi sebenarnya hanya beberapa baris lagi (menguraikannya dari dan merangkainya menjadi JSON).

Solusi yang saya temukan:

  • Jika saya membuat fungsi baru pada setiap render di sekitar fungsi setValue , itu benar-benar berfungsi.

    • tetapi ini bertentangan dengan saran pada [1] tentang menghindari pembuatan nilai baru.

  • Migrasikan ke kelas dan gunakan componentDidUpdate alih-alih useEffect .

    • Saya benar-benar menggunakan ini sekarang, karena berfungsi. Termasuk menyimpan referensi ke fungsi di negara bagian.


Apakah ada sesuatu yang seharusnya tidak berfungsi pada kode di bawah ini? efeknya dipicu dengan perubahan,
tetapi nilainya tidak diperbarui pada komponen yang dikonsumsi melalui hook. lihat kode repro [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-avoid-passing-callbacks-down
[2] : https://reactjs.org/docs/context.html#updating -context-from-a-nested-component
[3] : https://codesandbox.io/s/0yzjr8vnrv


hlcecpq

Question

Komentar yang paling membantu

Saya telah membuat demo yang efisien di Codesandbox [3].

Menurut saya, panggilan useContext ada dalam komponen yang sama dengan Provider . Dalam hal ini, mereka membaca konteks di atas Penyedia (yang default).

Nilai penyedia hanya memengaruhi konteks untuk komponen di dalamnya.

Ngomong-ngomong, jika Anda tidak mencoba menipu aturan Hooks dengan kode seperti [A, B].map(useContext) Anda mungkin akan menyadarinya lebih awal ;-)

Semua 3 komentar

Saya telah membuat demo yang efisien di Codesandbox [3].

Menurut saya, panggilan useContext ada dalam komponen yang sama dengan Provider . Dalam hal ini, mereka membaca konteks di atas Penyedia (yang default).

Nilai penyedia hanya memengaruhi konteks untuk komponen di dalamnya.

Ngomong-ngomong, jika Anda tidak mencoba menipu aturan Hooks dengan kode seperti [A, B].map(useContext) Anda mungkin akan menyadarinya lebih awal ;-)

hai Dan! terima kasih atas tanggapan yang cepat (: baru saja memperbaikinya untuk saya.

btw: useContext (melalui useStorage ) ada di dalam App , yang _is_ di dalam Provider dalam fungsi ReactDOM.render . (mungkin saya membuat contoh terlalu pendek untuk melihat ini bersarang).


solusi :

Saya baru saja menyelesaikannya dengan memodifikasi baris .map yang aneh: Saya melewatkan parameter observedBits , yang akhirnya diteruskan. Saya telah membacanya di sini di Masalah / PR, tetapi lupa tentangnya saat menerapkan, dan akhirnya mengacaukan perilaku tersebut.

Aaah kamu benar, aku salah membaca teladanmu. Ya observedBits adalah masalah di sini. Sepertinya jebakan, tapi kami juga tidak menyarankan untuk memanggil useContext secara dinamis jadi ..

Apakah halaman ini membantu?
0 / 5 - 0 peringkat