我有一个由WordPress预渲染的HTML页面和三个React组件:<App />
,<Component />
和<AnotherComponent />
。
HTML页面中有两个ID div容器(div
id="component"
和div
id="anotherComponent"
),它们是分开的,我想渲染React组件。他们也分享一些州。我想使用<App />
编写所有逻辑和事件处理,然后将状态(this.props.counter
)传递给每个组件。
我想为每个组件使用ReactDOM.render(<Component />, document.getElementById('component'));
并使用<App />
来控制逻辑,但我如何将状态传递给每个组件,以及我在render()
中的<App />
。
这个最好的方法是什么?
ReactDOM.render
就像React应用程序的主要方法。所有与反应相关的概念(如组件,状态和上下文)都从此处开始。您可以使用相同的容器DOM节点或不同的容器DOM节点在同一页面上多次调用ReactDOM.render
。如果容器相同,则会对其执行更新,并且仅在必要时改变DOM以反映最新的React元素。但是如果容器节点不同,它将创建两个不同的React根,并且它们完全相互独立。这两个React根之间没有共享状态或上下文,它就像在同一页面上运行两个不同的React应用程序一样。
此外,在将带有ReactDOM.render
的根元素渲染到容器节点之后,所有其他后代元素将由React在其中呈现,并且我们没有任何控制来改变它们被渲染的位置(将来会改变)。
因此,在您的情况下,如果要在不同的容器节点中呈现这两个组件,您将无法拥有保持共享状态或事件处理的App组件。但是,您可以创建两个不同的React根,并通过props共享它们之间的对象和方法。
const data = {/*...*/}
ReactDOM.render(<Component data={data} />,
document.getElementById('component'));
ReactDOM.render(<AnotherComponent data={data} />,
document.getElementById('anotherComponent'));
但是,如果您想在某些时候更改这些道具,则必须手动重新渲染根组件。例如,如果你有一个每秒更新的counter
变量,你必须用每个新值重新渲染你的根。
let couter = 0
setInterval(function(){
counter++
ReactDOM.render(<Component data={data} />,
document.getElementById('component'));
ReactDOM.render(<AnotherComponent data={data} />,
document.getElementById('anotherComponent'));
}, 1000)
另一个好的选择是使用类似Redux的状态管理库。你可以有一个store
并在两个根之间分享。如果你需要在两个根之间共享一个非常复杂的状态,我强烈推荐这种方法。
const store = createStore(/* ... */)
// ...
ReactDOM.render(
<Provider store={store}>
<Component />
</Provider>,
document.getElementById('component')
);
ReactDOM.render(
<Provider store={store}>
<AnotherComponent />
</Provider>,
document.getElementById('anotherComponent')
);
当您使用Redux时,您将使用Component
高阶分量将AnotherComponent
和store
连接到connect
。在引擎盖下,当你使用组件的subscribe方法更改状态时,这将store
你的组件更改为forceUpdate
并重新渲染组件。因此,只要您通过将操作分派给商店来更改状态,就不必手动调用ReactDOM.render
方法。