如何在消费者而不是提供者中更改上下文?

Posted

技术标签:

【中文标题】如何在消费者而不是提供者中更改上下文?【英文标题】:How to change context in Consumer instead of Provider? 【发布时间】:2020-03-02 04:27:35 【问题描述】:

我发现这个问题通过将所有上下文更改功能添加到最顶层的父级来回答这个问题。 React Context api - Consumer Does Not re-render after context changed

但这很尴尬,我想要在改变它的组件中改变上下文的函数。假设我有一个按钮可以更改内容中的某些内容,我希望在该组件中有 handleChange(),而不是用不属于那里的功能和状态阻塞我的父级。

这是否可以将上下文逻辑外包给组件?

【问题讨论】:

请尝试包含一些相关代码以更好地代表您的问题。 我没有这个代码 让sue添加javascript标签 【参考方案1】:

context 只是一种通过props 而无需担心层次结构的奇特技术。

与普通props 相比,数据流解耦是唯一的区别。因此,更改 context 的值需要注意一些事项。

当您需要更改父子之间的共享状态时,您需要提升您的状态并传递一种更改它的方法。与context 没有什么不同


假设以下提供者传递theme 和一种更改它的方式

export const context = createContext()
const  Provider  = context

export const ThemeProvider = ( children ) => 
    const [theme, setTheme] = useState( color: 'foo' )
    const value =  theme, setTheme 
    return (
        <Provider value=value>
            children
        </Provider>
    )

您仍然需要传递一个处理程序来更改状态。要从 ComponentThemeProvider 的后代)内部更改 theme,您可以这样做

import  useContext  from 'react'
import context from './ThemeProvider'

const Component = () =>
    const theme, setTheme = useContext(context)

    const handleChange = () => setTheme(color:'blue')

    return <button onClick=handleChange>Change</button>


通常(不一定)Providers 在***组件App.js 中声明

//App.js
import  ThemeProvider  from './ThemeProvider'

const App = () =>
    <ThemeProvider>
         <RestOffYourApp />
    </ThemeProvider>

【讨论】:

我会将 ThemeProvider 添加到 App.js 吗? 这只是一个如何修改你的上下文的例子 是的,我理解了这个例子,但是我想以这种方式使用它,我该如何将它添加到 App.js 中 更新答案【参考方案2】:

如果您不希望父级具有状态和状态更改功能,只需不要使用上下文 - 听起来本地 component state 就是您要寻找的全部。 p>

【讨论】:

不,组件应该是兄弟姐妹。因此,一个按钮应该在上下文中更改一个道具,并且同一级别的另一个兄弟应该更新该更改。【参考方案3】:

是的,你需要使用 useReducer。 https://reactjs.org/docs/hooks-reference.html#usereducer

您在useReducer 的帮助下创建了一个reducer,并将其传递给Context。之后,您可以从任何连接到上下文的组件中使用statedispatch

链接:

https://reactjs.org/docs/hooks-reference.html#usereducer https://medium.com/octopus-labs-london/replacing-redux-with-react-hooks-and-context-part-1-11b72ffdb533 When to use native React.useReducer Hook and how it differentiate from Redux https://www.simplethread.com/cant-replace-redux-with-hooks/

【讨论】:

或者你可以在父组件中使用多个useState,并通过Context传递。但在我看来,这不是最好的解决方案。 在基于类的应用程序中这可能吗? Hooks 只用在功能组件中

以上是关于如何在消费者而不是提供者中更改上下文?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中获取有关提供者上下文更改的网络数据

通过反应上下文 api 将子状态传递给父组件

在儿童中使用消费者的上下文

在消费者之外更新反应上下文?

来自库的反应上下文未在消费者中更新

CoreData 合并冲突显示托管对象版本更改而不是数据