React: フック:useStateが更新されないuseContext

作成日 2019年01月26日  ·  3コメント  ·  ソース: facebook/react

機能をリクエストしバグを報告しますか?

バグのよう

現在の動作は何ですか?

ネストされたコンテキストプロバイダーとuseContextフックが競合しているようで、更新は破棄されます。

期待される動作は何ですか?

コンテキストに接続するときは、 valueが変更されるたびに更新する必要があります。

この問題の影響を受けるReactのバージョンとブラウザ/ OSはどれですか?

  • 反応18.8.0-alpha.116.7.0-alpha.0でも再現)
  • ブラウザchrome 71
  • os :macOSSierra

詳細

localStorageの「接続」のクリーンアップに取り組んでいる間、
公式のreactドキュメントから2つの記事( [1][2] )をミックスしようとしました。フックを使用して実装しましたが、値が渡されていないようです。

codesandbox [3]合理化されたデモを

実際の実装はほんの数行です(JSONからの解析とJSONへの文字列化)。

私が見つけた回避策:

  • setValue関数の周りの各レンダリングで新しい関数を作成すると、実際に機能します。

    • しかし、これは、新しい値の作成を回避することについての[1]に関するアドバイスに反します。

  • クラスに移行し、使用componentDidUpdateの代わりにuseEffect

    • 私は実際にこれを使用しています。 関数への参照を状態に保存することを含みます。


以下のコードで動作してはいけないものはありますか? 効果は変更によってトリガーされます、
ただし、フックを介して消費するコンポーネントの値は更新されません。 再現コード[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


hlcecpq

Question

最も参考になるコメント

codesandbox [3]に合理化されたデモを掲載しました。

useContext呼び出しは、 Providerと同じコンポーネントに含まれているように見えます。 その意味で、彼らはプロバイダー(デフォルトのもの)ののコンテキストを読んでいます。

プロバイダーの値は、プロバイダー

ちなみに、 [A, B].map(useContext)ようなコードでフックのルールをだまそうとしなかった場合は、これにもっと早く気づいたかもしれません;-)

全てのコメント3件

codesandbox [3]に合理化されたデモを掲載しました。

useContext呼び出しは、 Providerと同じコンポーネントに含まれているように見えます。 その意味で、彼らはプロバイダー(デフォルトのもの)ののコンテキストを読んでいます。

プロバイダーの値は、プロバイダー

ちなみに、 [A, B].map(useContext)ようなコードでフックのルールをだまそうとしなかった場合は、これにもっと早く気づいたかもしれません;-)

やあダン! 迅速な対応に感謝します(:私のために修正しました。

ところで: useContextuseStorage経由)はAppにあり、 ReactDOM.render関数のProvider中にあります。 (多分私はこの入れ子を見るには例を短すぎました)。


解決策

私はその風変わりな.map行を変更することでそれを解決しました: observedBitsパラメーターを見逃し、それが渡されてしまいました。ここで問題/ PRで読んだのですが、忘れてしまいました実装するとき、そして振る舞いを台無しにすることになった。

ああ、あなたは正しいです。私はあなたの例を読み間違えました。 ええobservedBitsがここでの問題です。 落とし穴のように見えますが、 useContext動的に呼び出すこともお勧めしません。

このページは役に立ちましたか?
0 / 5 - 0 評価