React: 钩子:useState与useState不更新

创建于 2019-01-26  ·  3评论  ·  资料来源: facebook/react

您是否要请求功能或报告错误

似乎是个错误。 😕

目前的行为是什么?

嵌套的上下文提供程序和useContext钩子似乎冲突,更新被丢弃。

预期的行为是什么?

连接到上下文时,只要更改value ,它就会更新。

哪个版本的React,以及哪个浏览器/操作系统受此问题影响?

  • react18.8.0-alpha.1 (也复制到16.7.0-alpha.0
  • 浏览器chrome 71
  • 操作系统:macOS Sierra

更多细节

在清理localStorage“连接”时,
我尝试将官方的react文档中的2篇文章( [1][2] )混合在一起,我已经用钩子实现了它,但是价值似乎没有传递。

我在codeandbox [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

最有用的评论

我在codeandbox [3]上做了一个简化的演示。

在我看来,您的useContext通话与Provider属于同一组件。 从这种意义上讲,他们正在读取提供程序上方的上下文(默认值)。

提供程序的值仅影响其内部组件的上下文。

顺便说一句,如果您不尝试使用[A, B].map(useContext)类的代码欺骗Hooks规则,您可能会很快注意到这一点;-)

所有3条评论

我在codeandbox [3]上做了一个简化的演示。

在我看来,您的useContext通话与Provider属于同一组件。 从这种意义上讲,他们正在读取提供程序上方的上下文(默认值)。

提供程序的值仅影响其内部组件的上下文。

顺便说一句,如果您不尝试使用[A, B].map(useContext)类的代码欺骗Hooks规则,您可能会很快注意到这一点;-)

嘿,丹! 感谢您的快速回复(:为我修复了它。

顺便说一句: useContext (经由useStorage )是内部App ,其中_is_内部ProviderReactDOM.render功能。 (也许我使示例太短了以至于看不到此嵌套)。


解决方案

我只是通过修改古怪的.map行来解决它:我错过了observedBits参数,最终被传递了,我已经在Issues / PRs中阅读了它,但是忘记了在实施时,最终导致行为混乱。

啊,你是对的,我看错了你的榜样。 是的, observedBits是这里的问题。 似乎是一个陷阱,但是我们也不建议如此动态地调用useContext

此页面是否有帮助?
0 / 5 - 0 等级