共享状态时在不同容器中渲染组件

pmq*_*mqa 3 reactjs

我有一个HTML页面由WordPress的预渲染和三个反应的组分:<App /><Component /><AnotherComponent />

HTML页面(div id="component"div id="anotherComponent")内有两个ID div容器,它们是分开的,我想在其上渲染React组件。他们也共享一些状态。我想用来<App />编写所有逻辑和事件处理,然后将状态(this.props.counter)传递给每个组件。

在此处输入图片说明

我想ReactDOM.render(<Component />, document.getElementById('component'));对每个组件使用,并使用<App />来控制逻辑,但是我如何将状态传递给每个组件,以及我render()在组件中要做什么<App />

最好的方法是什么?

Tha*_*ara 5

ReactDOM.render就像React应用程序的主要方法一样。所有与反应相关的概念(例如组件,状态和上下文)都从此处开始。您可以ReactDOM.render在同一页面上使用相同的容器DOM节点或不同的容器DOM节点多次调用。如果容器相同,它将对它执行更新,并且仅在必要时对DOM进行更改以反映最新的React元素。但是,如果容器节点不同,它将创建两个不同的React根,并且它们彼此完全独立。这两个React根目录之间没有共享的状态或上下文,这很像在同一页面上运行两个不同的React应用程序。

同样,在将根元素渲染ReactDOM.render到容器节点中之后,所有其他后代元素也将由React渲染到其内部,我们没有任何控件可以更改渲染它们的位置(将来会更改)。

因此,在您的情况下,如果要在不同的容器节点中呈现这两个组件,则将无法拥有保持共享状态或事件处理的App组件。但是相反,您可以创建两个不同的React根,并通过prop在它们之间共享对象和方法。

const data = {/*...*/}

ReactDOM.render(<Component data={data} />,
  document.getElementById('component'));

ReactDOM.render(<AnotherComponent data={data} />,
  document.getElementById('anotherComponent'));
Run Code Online (Sandbox Code Playgroud)

但是,如果您想在某些时候更改这些道具,则必须手动重新渲染根组件。例如,如果您有一个counter每秒更新的变量,则必须使用每个新值重新渲染根。

let couter = 0

setInterval(function(){
  counter++

  ReactDOM.render(<Component data={data} />,
    document.getElementById('component'));

  ReactDOM.render(<AnotherComponent data={data} />,
    document.getElementById('anotherComponent'));

}, 1000)
Run Code Online (Sandbox Code Playgroud)

另一个很好的选择是使用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')
);
Run Code Online (Sandbox Code Playgroud)

使用Redux时,您可以将Component和连接AnotherComponentstore具有connect较高顺序的组件。在后台,这将使您的组件订阅store更改并在使用组件的forceUpdate方法更改状态时重新呈现该组件。因此ReactDOM.render,只要您通过将操作分派到商店来更改状态,就不必手动调用该方法。