从树外部以编程方式设置反应上下文提供者状态
set react context provider state programatically from outside the tree
我正在将 React 添加到现有的网络应用程序中。现在,我有选择地替换页面的某些部分,在不同的 div 中呈现不同的组件。出于这个原因,我没有一棵树可以挂起所有组件。我想使用一个上下文提供程序在所有这些组件之间共享上下文信息,但是由于我没有一棵树,所以我不能让它们都挂在同一个上下文提供程序上。
有没有办法使用这样定义的默认上下文?
const MyContext = React.createContext(some_data);
并且没有挂起组件的提供者,而只有消费者?
<MyContext.Consumer>...</MyContext.Consumer>
它适用于默认值,但后来我不知道如何更改此默认上下文的值。
我的理解是否正确,这是否适用于所有依赖提供商的消费者?或者有没有办法以编程方式设置默认上下文的值?还有其他方法可以解决这个问题吗?
您可能需要查看 portals。这使您可以定位特定元素以将 React 树渲染到其中。你可以有一个组件树,在你的例子中有一个声明的上下文,并将你的所有组件挂在它之外,而不管它是如何呈现到 DOM.
This article,在 "legacy applications" 下,您可以很好地了解如何做我所说的事情。
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'));
我正在将 React 添加到现有的网络应用程序中。现在,我有选择地替换页面的某些部分,在不同的 div 中呈现不同的组件。出于这个原因,我没有一棵树可以挂起所有组件。我想使用一个上下文提供程序在所有这些组件之间共享上下文信息,但是由于我没有一棵树,所以我不能让它们都挂在同一个上下文提供程序上。
有没有办法使用这样定义的默认上下文?
const MyContext = React.createContext(some_data);
并且没有挂起组件的提供者,而只有消费者?
<MyContext.Consumer>...</MyContext.Consumer>
它适用于默认值,但后来我不知道如何更改此默认上下文的值。
我的理解是否正确,这是否适用于所有依赖提供商的消费者?或者有没有办法以编程方式设置默认上下文的值?还有其他方法可以解决这个问题吗?
您可能需要查看 portals。这使您可以定位特定元素以将 React 树渲染到其中。你可以有一个组件树,在你的例子中有一个声明的上下文,并将你的所有组件挂在它之外,而不管它是如何呈现到 DOM.
This article,在 "legacy applications" 下,您可以很好地了解如何做我所说的事情。
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'));