React.js为this.props.children设计实践

时间:2016-10-25 12:50:43

标签: javascript reactjs

我想我正在快速使用React,但有一件事我不确定是最好的。

我有一个包含三个小部件的页面。由于我希望在所有小部件上具有相同的行为和样式,因此我将每个组件包装在<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <div id= "main"> <div id="div1" style="padding-left: 20px;"> <input type="checkbox" class="chkBox" > <input type="number" id="len1" disabled = "disabled"/> <a href='#' id="btn-save" class="glyphicon glyphicon-floppy-save save" style="display: none;" >div1</a> </div> <div id="div2" style="padding-left: 20px;"> <input type="checkbox" class="chkBox" > <input type="number" id="len2" disabled = "disabled"/> <a href='#' id="btn-save2" class="glyphicon glyphicon-floppy-save save" style="display: none;" >div2</a> </div> <div id="div3" style="padding-left: 20px;"> <input type="checkbox" class="chkBox" > <input type="number" id="len3" disabled = "disabled"/> <a href='#' id="btn-save3" class="glyphicon glyphicon-floppy-save save" style="display: none;" >div3</a> </div> </div>标记中,该标记负责样式和布局。这种方法的一个原因是我还使用了我不想要<PageAreaTemplate/>或其他模板的内部组件。

PageAreaTemplate我简单地将PageAreaTemplate包裹在样式所需的组件中。

现在我需要让一些小部件为this.props.children中的标题添加一个工具栏(每个小工具不同)(如果它被模板包装)。克隆PageAreaTemplate并在children中添加函数setToolbar是可行的,但这当然感觉不对。

您的经历是实现这一目标的最佳途径?

2 个答案:

答案 0 :(得分:1)

接受子元素,克隆并稍微修改它是相当常见的做法 - 无论是添加其他属性还是功能。

function renderChildren(props) {
  return React.Children.map(props.children, child => {
    return React.cloneElement(child, {
      setToolbar: () => ()
    })
  })
}

这只是像你所说的那样扩展了当前的孩子,Object.assign而不是操纵当前的孩子。

上面的功能应该允许你添加所需的任何逻辑,以确保你得到你想要的 - 即。检查组件的类型或某个属性值。

答案 1 :(得分:0)

我使用@ kelly-j-andrews建议的方法解决了我的问题,在父组件上设置工具栏但是它需要更多技巧来真正对工具栏工作进行更新并且可见(内部组件的工具栏部分) )通过设置内部组件的状态,因为内部的更新不会触发父组件的渲染。

我最终做的是:

  1. 在外部组件(PageAreaTemplate)中,我克隆了每个孩子并根据上面的例子对其进行了修改。
  2. 在内部组件中,在生命周期函数调用setToolbar中执行componentDidMount以设置初始组件
  3. 由于单击工具栏上的按钮会更改内部组件的状态,我再次在setToolbar上设置工具栏(componentDidUpdate)以强制渲染外部组件。在早期阶段调用setToolbar会生成一个反映更新前状态的工具栏。
  4. 这可能不是什么新东西,但由于我的问题不仅是能够在父级中设置组件,而且还确保内部组件中的状态在工具栏中正确反映,我回答了我自己的问题。

    它仍然不觉得它是最佳解决方案,但同样,它还在工作......!