通过道具

时间:2015-11-04 10:24:03

标签: reactjs redux

我已经使用Redux几个星期了,我对它非常满意,我已经习惯了Redux的方式。我正在使用React。还有很多东西可以学习,因为这两件事对我来说都是新的。

我有一个问题 - 也许我做错了什么......让我告诉你:

我有一个如下所示的组件结构:

App  //root of the application aka smart component
  CampaignTable 
    CampaignHeaderRow 
      CampaignHeader 
    CampaignDataRow
      CampaignData

App组件初始化为(仅相关代码):

import * as DashboardActions from '../actions.js'

function select(state){
  return {
    campaigns: state.campaigns,  // array of campaign objects, has name, id, time created etc
    order: state.order // sort format "byWhichField" 
                       // will affect the way how campaigns are displayed
  }
}

function mapDispatchToProps(dispatch){
  return bindActionCreators(DashboardActions, dispatch) 
}

export default connect(select, mapDispatchToProps)(App);

App现在可以访问状态和所有操作作为道具。

我现在看到的问题是:

我希望 CampaignHeader 触发将更改 state.order 状态的操作。假设我将在 CampaignHeader 中点击<th>Text</th>。这将触发更改 state.order 的操作,这将进一步影响下次重新渲染的广告系列顺序。

所以我在 App 道具中提供了我的操作。把它传递给 CampaignHeader 我必须:

  • 将其传递给 CampaignHeader 作为道具
  • 将其分配给 CampaignHeader 中的变量,并将其作为道具传递给 CampaignHeaderRow
  • 将其分配给 CampaignHeaderRow 中的变量,并将其作为道具传递给 CampaignHeader
  • 将其分配给 CampaignHeader 中的变量,并在onClick事件中触发操作....

这是很多样板,作业和包包传递!只是为了解决问题。

沿途的所有组件都知道此操作。

当我决定实施此功能时,我打开了 CampaignHeader 组件文件。我添加了逻辑并调用了操作,我已将操作添加到操作文件中。我所需要的只是获得一套道具。 CampaignHeader 组件不会持有对其父级的引用,因此我不知道应该从哪里注入此道具(在此示例中显而易见但我希望您能得到一点)。

如果我的组件结构更深入怎么办?

这种做法是否正确?

我能否以不同方式解决此问题?

更新:

@Errorpro建议将单一操作 state.order 连接到 CampaignHeader 是否可以?

担心:如果我一直这样做,我会一直这样做。

3 个答案:

答案 0 :(得分:1)

如果您使用redux,您应该了解哑巴和智能组件。所以我们使用这个结构:

component
  index.js
  Component.js
  ComponentContainer.js

哑组件只是获取道具并渲染它。智能组件更有趣。这是:

export default compose(
  relay({
    fragments: {
      viewer: () => Relay.QL`
        fragment on Viewer {
           any data from relay
        }
      `,
    },
  }),
  connect(
    null,
    {
      onCreate: createUserAction,
    },
    (stateProps, actionProps, parentProps) => ({
      ...parentProps,
      onCreate={() => actionProps.onCreate('user')},
    })
  ),
)(Component); 

因此,parentProps和onCreate函数将在哑组件的道具中。在那里你可以使用this.props.onCreate并调用它或将它传递得更远。

答案 1 :(得分:1)

将行动 - 像任何其他道具一样 - 从父母传给孩子到孙子等是惯用的反应方式。在我看来,你的方法是正确的;即使感觉不对。

但有几种选择。

React中有一个名为context的功能。上下文允许将字段从较高阶组件传递到较低阶组件,同时跳过中间人。但是,这是一个实验性功能,所以我建议暂时不要使用它。 https://facebook.github.io/react/docs/context.html

此外,还有一种Redux特定的方式,您可以在其中选择一个&#34;智能组件&#34; (在Redux意义上)。也就是说,将类导出包装在connect函数中以将其直接插入到存储中,就像对Root节点一样。

我个人倾向于坚持自上而下的方式。可能涉及到相当多的样板文件,但至少这意味着您的应用程序很容易被推理。

答案 2 :(得分:1)

在Redux github回购的问题部分有一个讨论,关于使用多个连接是否可以,或者如果一切都应该从顶部通过道具传递下来,并且在那里Dan Abramov(Redux的创建者说:< / p>

  

[...]

     

没有人提倡单一连接。

     

[...]

     

“单一”仅指我们在其中创建的小应用程序   例。请随时修改文档以更好地澄清这一点。一世   我现在忙于其他项目,所以请不要指望这个问题   除非有人做公关,否则不要动。你也可以这样做。

评论可能会在上下文中确定,因此请查看整个问题主题https://github.com/rackt/redux/issues/419#issuecomment-140782462