热交换React / Redux容器组件

时间:2016-06-16 18:18:30

标签: reactjs redux

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

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

我对动态解决方案的第一个(天真)实验涉及以下函数,用于将给定组件渲染到主机div中(我使用术语&#34;主机&#34;而不是&#34;容器& #34;为了避免与Dan Abramov的&#34;容器组件&#34;)的概念产生歧义:

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

这适用于[简单]表示组件 - yay ...当然,这是没用的,因为新渲染的组件没有任何道具。

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

  

未捕获的不变违规:找不到&#34;存储&#34;在任何一个   &#34;连接(借款人)&#34;的背景​​或道具。包裹根   a中的组件,或明确传递&#34; store&#34;作为支柱   &#34;连接(借款人)&#34;

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的实验性上下文功能。这通常应该保留给图书馆。

因此...

Q1。是否有一种推荐的方式来动态呈现组件并以无缝方式将其连接到redux存储,就好像它是静态组件层次结构的一部分(包括保留时间旅行调试而不是搞砸了React的VDOM对帐过程)?

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

Q3。关于VDOM对帐,我的方法有什么性能影响?

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

编辑:我已经破坏了上述内容,因为我认为任何路由器解决方案都会封装在HOC中,而componentName只会通过props传递给相关的实际演示组件。

1 个答案:

答案 0 :(得分:0)

似乎反应路由器是你在这里尝试做的更好的案例。我不确定为什么你会认为它仅适用于简单的用户界面。从我收集到的内容中,您正在准确地描述了路由器将为您做什么......

<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>

这会在您的网址中看起来像这样到达这些页面......

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

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

您不一定需要主要组件和父路线,但您必须在反应路由器中进行重定向,或者只是为初始组件渲染一个页面&#39; / &#39;