【问题标题】:Rendering components in different containers while sharing state在共享状态的同时在不同的容器中渲染组件
【发布时间】:2017-11-06 11:43:40
【问题描述】:

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

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

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

用这个最好的方法是什么?

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    ReactDOM.render 类似于 React 应用程序的 main 方法。所有与 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 时,你会将你的 ComponentAnotherComponent 连接到带有 connect 高阶组件的 store。在后台,这将 subscribe 您的组件更改为 store 并在使用组件的 forceUpdate 方法更改状态时重新呈现组件。因此,您不必手动调用 ReactDOM.render 方法,只要通过向 store 发送操作来更改状态即可。

    【讨论】:

    • 这是一个非常详细的答案,我完全开悟了。非常感谢 :) PS:只是一个问题,当状态更新时,Redux 会自动运行 ReactDOM.render 方法吗?
    • @pmqa 很高兴它对您有所帮助。我更新了答案,提供了有关 Redux 方法如何工作的更多详细信息。
    • 太棒了。 Redux 方法看起来就是这样。再次感谢 Tharaka。
    • 我想也许我是互联网上唯一这样做的人,但很高兴找到你的答案,谢谢!在我的例子中,我有一个绝对定位的覆盖组件,当用户单击缩略图时我想显示它,但是这两个组件由 html 文件中的其他元素分隔,就像在这个问题中一样。我不确定的一件事是是否可以在组件 A 的单击处理程序中调用 ReactDOM.render(ComponentA) 来隐藏组件 A(关闭按钮)(我将 visible={false} 作为道具传递。但是唯一的选择是从道具更新状态......似乎很糟糕。
    猜你喜欢
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    相关资源
    最近更新 更多