从树外部以编程方式设置反应上下文提供者状态

Posted

技术标签:

【中文标题】从树外部以编程方式设置反应上下文提供者状态【英文标题】:set react context provider state programatically from outside the tree 【发布时间】:2019-02-23 15:52:04 【问题描述】:

我正在将 React 添加到现有的 web 应用中。现在,我选择性地替换页面的某些部分,在不同的 div 中呈现不同的组件。出于这个原因,我没有一棵挂在所有组件上的树。我想使用一个上下文提供程序在所有这些组件之间共享上下文信息,但由于我没有一棵树,我不能让它们都挂在同一个上下文提供程序上。

有没有办法使用这样定义的默认上下文?

const MyContext = React.createContext(some_data);

并且没有提供者挂起哪些组件,而只有消费者?

<MyContext.Consumer>...</MyContext.Consumer>

它适用于默认值,但是我不知道如何更改此默认上下文的值。

我的理解是否正确,这适用于所有从提供商处挂起的消费者?或者有没有办法以编程方式设置默认上下文的值?还有其他方法可以解决这个问题吗?

【问题讨论】:

【参考方案1】:

React 上下文完全依赖于组件层次结构,它不能用于为不相关的 React 小部件提供通用上下文。

如果页面由多个 React 小部件组成,它们需要有一个共同的父级。这可以通过门户来完成,这样整个页面就不需要转换为 React 组件了。

这是example:

<div id="App"></div>
<h2>Foo widget</h2>
<div id="FooWidget"></div>
<h2>Bar widget</h2>
<div id="BarWidget"></div>

class App extends Component 
  render() 
    return <FoobarContext.Provider value=foo: 'foo', bar: 'bar'>    
      ReactDOM.createPortal(<FooWidget />, document.getElementById('FooWidget')) 
      ReactDOM.createPortal(<BarWidget />, document.getElementById('BarWidget')) 
    </FoobarContext.Provider>;
  


const FooWidget = props => <FoobarContext.Consumer>
  ( foo ) => foo
</FoobarContext.Consumer>;

...

ReactDOM.render(<App />, document.getElementById('App'));

【讨论】:

【参考方案2】:

您可能想查看portals。这让你可以定位特定元素来渲染你的 React 树。您可以拥有一个单独的组件树,在您的示例中声明上下文,并将所有组件挂起,而与它如何呈现到 DOM 无关。

This article,在“遗留应用程序”下,您可以很好地了解如何执行我所说的操作。

【讨论】:

以上是关于从树外部以编程方式设置反应上下文提供者状态的主要内容,如果未能解决你的问题,请参考以下文章

为啥反应上下文提供程序组件呈现两次[重复]

当提供者组件父状态发生变化时,为啥不能更新子组件中的值(带有反应上下文)?

如何将函数传递给自己的反应上下文提供程序,让您编辑状态?

可以以编程方式提供 iOS 预测键盘上下文/源文本吗?

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

即时反应上下文 api 更新状态