React: الخطافات: لا يتم تحديث useContext مع useState

تم إنشاؤها على ٢٦ يناير ٢٠١٩  ·  3تعليقات  ·  مصدر: facebook/react

هل تريد طلب ميزة أو الإبلاغ عن خطأ ؟

يبدو أنه خطأ . 😕

ما هو السلوك الحالي؟

يبدو أن موفر السياق المتداخل و hooks useContext متعارضين ، ويتم تجاهل التحديثات.

ما هو السلوك المتوقع؟

عند الاتصال بسياق ، يجب تحديثه عندما يتغير value .

ما إصدارات React وأي متصفح / نظام تشغيل متأثر بهذه المشكلة؟

  • التفاعل : 18.8.0-alpha.1 (مستنسخ أيضًا على 16.7.0-alpha.0 )
  • المتصفح : chrome 71
  • نظام التشغيل : macOS Sierra

المزيد من التفاصيل

أثناء العمل على تنظيف "اتصال" التخزين المحلي ،
حاولت مزج مقالتين ( [1] & [2] ) من وثائق التفاعل الرسمية ، لقد طبقتها باستخدام الخطافات ، لكن يبدو أن القيمة لا تمر.

لقد قدمت عرضًا توضيحيًا مبسطًا على codeandbox [3] .

التنفيذ الفعلي ليس أكثر من سطرين (تحليله من وترقيمه إلى JSON).

الحلول التي وجدتها:

  • إذا قمت بإنشاء دالة جديدة في كل عرض حول الدالة setValue ، فإنها تعمل بالفعل.

    • لكن هذا يتعارض مع نصيحة [1] حول تجنب إنشاء قيم جديدة.

  • قم بترحيلها إلى فصل دراسي واستخدم componentDidUpdate بدلاً من useEffect .

    • أنا في الواقع أستخدم هذا الآن ، لأنه يعمل. بما في ذلك حفظ إشارة إلى الوظيفة في الدولة.


هل هناك أي شيء لا يجب أن يعمل على الكود أدناه؟ يتم تشغيل التأثير مع التغييرات ،
لكن القيمة لا يتم تحديثها على المكونات التي تستهلك عبر الخطاف. انظر رمز 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-Prevention-pass-callbacks-down
[2] : https://reactjs.org/docs/context.html#updating -context-from-a-nested-component
[3] : https://codesandbox.io/s/0yzjr8vnrv


hlcecpq

Question

التعليق الأكثر فائدة

لقد قمت بوضع عرض توضيحي مبسط على codeandbox [3].

يبدو لي أن مكالماتك useContext موجودة في نفس المكوّن مثل Provider . وبهذا المعنى ، فهم يقرؤون السياق أعلى الموفر (الافتراضي).

تؤثر قيمة المزود فقط على سياق المكونات الموجودة بداخله .

بالمناسبة ، إذا لم تحاول خداع قواعد الخطافات برمز مثل [A, B].map(useContext) فربما لاحظت هذا عاجلاً ؛-)

ال 3 كومينتر

لقد قمت بوضع عرض توضيحي مبسط على codeandbox [3].

يبدو لي أن مكالماتك useContext موجودة في نفس المكوّن مثل Provider . وبهذا المعنى ، فهم يقرؤون السياق أعلى الموفر (الافتراضي).

تؤثر قيمة المزود فقط على سياق المكونات الموجودة بداخله .

بالمناسبة ، إذا لم تحاول خداع قواعد الخطافات برمز مثل [A, B].map(useContext) فربما لاحظت هذا عاجلاً ؛-)

يا دان! شكرا على الرد السريع (: فقط أصلحه لي.

راجع للشغل: يوجد useContext (عبر useStorage ) داخل App ، وهو _ داخل Provider في دالة ReactDOM.render . (ربما جعلت المثال أقصر من أن أرى هذا التداخل).


الحل :

لقد قمت بحلها للتو عن طريق تعديل هذا السطر الملتوي .map : لقد فاتني المعلمة observedBits ، والتي انتهى بها الأمر وقد قرأت عنها هنا في المشاكل / العلاقات العامة ، لكنني نسيت ذلك عند التنفيذ ، وانتهى الأمر بالعبث بالسلوك.

آآآه أنت محق أنا أخطأت في مثالك. نعم ، observedBits هي المشكلة هنا. يبدو وكأنه مأزق ، ولكن بعد ذلك لا نوصي أيضًا باستدعاء useContext على الإطلاق بشكل ديناميكي ..

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات