機能をリクエストしバグを報告しますか?
バグのよう
現在の動作は何ですか?
ネストされたコンテキストプロバイダーとuseContext
フックが競合しているようで、更新は破棄されます。
期待される動作は何ですか?
コンテキストに接続するときは、 value
が変更されるたびに更新する必要があります。
この問題の影響を受けるReactのバージョンとブラウザ/ OSはどれですか?
18.8.0-alpha.1
( 16.7.0-alpha.0
でも再現)chrome 71
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 :
codesandbox [3]に合理化されたデモを掲載しました。
useContext
呼び出しは、 Provider
と同じコンポーネントに含まれているように見えます。 その意味で、彼らはプロバイダー(デフォルトのもの)の上のコンテキストを読んでいます。
プロバイダーの値は、プロバイダー内の
ちなみに、 [A, B].map(useContext)
ようなコードでフックのルールをだまそうとしなかった場合は、これにもっと早く気づいたかもしれません;-)
やあダン! 迅速な対応に感謝します(:私のために修正しました。
ところで: useContext
( useStorage
経由)はApp
にあり、 ReactDOM.render
関数のProvider
中にあります。 (多分私はこの入れ子を見るには例を短すぎました)。
解決策:
私はその風変わりな.map
行を変更することでそれを解決しました: observedBits
パラメーターを見逃し、それが渡されてしまいました。ここで問題/ PRで読んだのですが、忘れてしまいました実装するとき、そして振る舞いを台無しにすることになった。
ああ、あなたは正しいです。私はあなたの例を読み間違えました。 ええobservedBits
がここでの問題です。 落とし穴のように見えますが、 useContext
動的に呼び出すこともお勧めしません。
最も参考になるコメント
useContext
呼び出しは、Provider
と同じコンポーネントに含まれているように見えます。 その意味で、彼らはプロバイダー(デフォルトのもの)の上のコンテキストを読んでいます。プロバイダーの値は、プロバイダー内の
ちなみに、
[A, B].map(useContext)
ようなコードでフックのルールをだまそうとしなかった場合は、これにもっと早く気づいたかもしれません;-)