【问题标题】:Is there any way share state between有什么方法可以共享状态
【发布时间】:2016-01-28 06:41:19
【问题描述】:

我有四个组件:PanelPanelHeaderPanelBodyPanelFooter 它们的组成如下:

<Panel>
    <PanelHeader>
        some title
    </PanelHeader>
    <PanelBody>
        <div>
            main content
        </div>
    </PanelBody>
    <PanelFooter>
        footer content
    </PanelFooter>
</Panel>

我也有多个路线,我想在其中看到 Panel,但内容不同。

一个明显的解决方案是为每个路由创建组件,每个组件都有自己的Panel

但就我而言,我想在路线之间添加一些变形动画(更改面板的高度、幻灯片主体、淡入淡出页脚等)。为此,我需要将所有内容渲染为完全相同的PanelPanelHeaderPanelBodyPanelFooter 实例,因此上述解决方案不起作用。

所以我需要将我的路由组件拆分为每个PanelXXX 的三个组件,问题是这些组件需要对彼此的事件做出反应。

目前有以下几点:

  • 我无法创建另一个中介组件来控制这三个部分组件,因为在渲染之前我将无法访问它的 API(因此我无法实现 getter 方法,例如 getHeader())。
  • 我可以将它们全部连接到 redux,但接缝太复杂了。
  • 另一种解决方案是创建非 React 对象来共享状态,但在这种情况下,我需要在此对象之后进行清理以克服内存泄漏。与 redux 的连接也会很棘手。这种方法在我看来不是那么干净。
  • 我也可以用透明背景作弊,这样我就可以有一个Panel,也可以有多个PanelHeaders等等。但是在这种情况下,我需要将有关动画的知识传播给所有子组件。

有没有人知道在 React 中有任何其他方法可以做到这一点?或者我应该从以上几点中选择一个?

【问题讨论】:

  • 把这个评论留给来这里的人,试图决定是否使用 Redux,一般来说。我发现使用 npx create-react-app my-app --template redux 安装的 create react app 模板对学习 redux 非常有帮助。

标签: reactjs


【解决方案1】:

我认为您所描述的场景和您提出的问题正是使用 Flux 的合理性。 Redux 是一种选择。我们使用原始的 Facebook 库使用了普通的 Flux 实现,并且取得了巨大的成功。它有一个陡峭的学习曲线,但是一旦你开始了解它,你所面临的问题就会恰好适合基础架构。

【讨论】:

  • 好的。我会将您的答案标记为正确,因为我在这里看到的唯一一个选项是通过全局共享状态绑定所有部分组件。但我预计有人会提出一种使用中间本地状态来解决问题的方法。
  • @SleepWalker 我完全理解,但是你的建议是一种反模式,使用 Flux,一旦你了解它,这些问题就很容易管理。
  • 不。 Store 不需要知道组件特定的状态和通信。 Store 用于业务逻辑特定状态。通常,您使用组件的状态来存储一些中间状态,直到您收集触发操作所需的所有数据。此操作将在某些事件处理程序中触发。但在我的情况下,我在一个组件中有一个按钮(事件处理程序),而用于在其他组件中收集数据并在这个地方使用 Store 的 UI 是一种难闻的气味,但我还找不到更好的方法来解决这个问题。
  • @SleepWalker - 不完全是。您所说的对于父组件和子组件都是正确的。如果您接受 Flux 架构,则兄弟组件不应直接相互控制。模式是按钮组件触发一个动作,然后将该动作分派到商店。商店更新数据并触发更改事件。另一个兄弟订阅更改事件,获取新数据并根据需要更新视图。
【解决方案2】:

听起来您可以从使用this.props.children 中受益。

路由器

<Router history={createBrowserHistory()}>
    <Route path="/" component={App}>
        <IndexRoute component={DefaultView} />
        <Route path="foopath" component={FooView} />
        <Route path="barpath" component={BarView} />
    </Route>
</Router>

App.js

...

render: function() {
    return (
        <Panel>
            {this.props.children}
        </Panel>
    );
}

...

DefaultView.js

render: function() {
    <div>
        <PanelHeader>
            FooHeader
        </PanelHeader>
        <PanelBody>
            FooContent
        </PanelBody>
        <PanelFooter>
            FooFooter
        </PanelFooter>
    </div>
}

你可以阅读更多关于 React 的 children here.

【讨论】:

  • 抱歉,但我的意思是,我也需要单例 PanelHeaderPanelBodyPanelFooter。我已经更新了问题以更清楚。
猜你喜欢
  • 2010-10-14
  • 2023-04-03
  • 1970-01-01
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
  • 1970-01-01
相关资源
最近更新 更多