【问题标题】:Hot Swapping React/Redux Container Components热交换 React/Redux 容器组件
【发布时间】:2016-10-18 09:46:47
【问题描述】:

我正在探索 react/redux,我正在尝试找出实现多步骤向导组件的最佳方法,其中下一个“步骤”(即组件)在运行时动态确定 基于服务器端工作流规则。我查看了 redux-form 和其他类似向导的组件,但只从 redux-form 中看到了像这个示例这样的 硬编码 步骤(为简洁起见,省略了道具):

return (<div>
    {page === 1 && <WizardFormFirstPage />}
    {page === 2 && <WizardFormSecondPage/>}
    {page === 3 && <WizardFormThirdPage />}
  </div>
)

我对动态解决方案的第一个(幼稚)实验涉及以下用于将给定组件渲染到主机 div 的函数(我使用术语“主机”而不是“容器”以避免与 Dan Abramov 的“容器组件”):

showComponent(componentName) {
  let renderFunc = React.createElement(components[componentName], null);
  render(renderFunc, this.refs['hostDiv']);
}

这适用于 [simple] 展示组件 - 是的……当然,这是没用的,因为新渲染的组件没有得到任何道具。

我的下一个实验是看看这是否适用于与 redux 连接的 container 组件。你肯定猜到了,我失败得很惨。如果componentName 指的是容器组件,我得到:

未捕获的不变违规:在任一 “连接(借款人)”的上下文或道具。要么包裹根 a 中的组件,或显式将“store”作为道具传递给 “连接(借款人)”。

https://github.com/reactjs/react-redux/blob/ea53d6fb076359a864a1d543568d951d4b3eab3d/src/components/connect.js#L86

错误消息告诉我,将null 作为第二个参数传递给createElement() 是多么愚蠢。所以这是下一次迭代:

showComponent(componentName) {
  const { store } = this.context;
  let renderFunc = React.createElement(components[componentName], { store });
  render(renderFunc, this.refs['hostDiv']);
}. 

这让 redux 很高兴并且似乎可以工作。但是,我对使用 React 的实验性上下文功能感觉不太好。这通常应该为图书馆保留。


所以...

第一季度。是否有推荐的方法来动态渲染组件并以无缝方式将其连接到 redux 存储,就好像它是静态组件层次结构的一部分(包括保留时间旅行调试和不搞砸 React 的 VDOM 协调过程)?

第二季度。有没有人预见到我的方法有任何问题(除非使用上下文)?

第三季度。关于 VDOM 协调,我的方法对性能有何影响?

注意:我标记为“react-router”是因为我也对基于路由器的方法持开放态度。请记住,直到运行时我才会知道我的路线。我知道 react-router 支持带有代码拆分的动态路由,但我不确定我是否可以在运行时注入/替换新路由。

编辑:我对上述内容进行了抨击,因为我认为任何路由器解决方案都将封装在 HOC 中,而 componentName 将简单地通过道具传递给相关的实际演示组件。

【问题讨论】:

  • Q1,你看过react-router的路由吗?你可以有dynamic params in url to match
  • @Kujira 嗨,我查看了 react-router 的参数,我认为这肯定适用于相对简单的 UI。诚然,我必须进一步探索这一点,以证明它适用于一个复杂的应用程序,该应用程序可能在多个嵌套选项卡中包含多个任务向导实例。

标签: reactjs redux


【解决方案1】:

看起来 react-router 是你在这里尝试做的更好的情况。我不知道为什么你会认为它只是一个简单的用户界面。根据我收集到的信息,您正在准确描述 react-router 将为您做什么......

<Router>
    <Route to="/" component={Main}>
        <Route to="1" component={WizardFormFirstPage} />
        <Route to="2" component={WizardFormSecondPage} />
        <Route to="3" component={WizardFormThirdPage}>
            <Route to=":someId" component={WizardFormThirdPageWithId} />
        </Route>
    <Route>
</Router>

在您的 url 中看起来像这样可以访问这些页面...

http://localhost/1
http://localhost/2
http://localhost/3

只是为了好玩,我在其中一条路线中添加了一个孩子,这样您就可以看到您可以获得一个传递给 WizardFormThirdPageWithId 的参数。该网址看起来像 http://localhost/3/2345 和 WizardFormThirdPageWithId 中 this.props.params.someId 的值将等于 2345。

您不一定需要 Main 组件和父路由,但您必须在 React 路由器中进行重定向,或者只为初始“/”呈现您的页面之一。

【讨论】:

    猜你喜欢
    • 2017-07-06
    • 1970-01-01
    • 2017-06-13
    • 2017-02-09
    • 2017-09-10
    • 2016-10-13
    • 1970-01-01
    • 2016-08-02
    • 1970-01-01
    相关资源
    最近更新 更多