React使用children渲染子组件方法
在Vue里, 渲染子组件可以使用slot插槽, 不仅能指定子组件渲染位置, 还能通过指定name属性来有选择地渲染, 但是在React里就没有这种组件了。
当然, React也不是没有办法实现slot组件的功能, 通常就是用 this.props.children 这个属性:
class Parent extends Component {
  render() {
    return (<div>
      <div>
        这是正常的内容
      </div>
      { //这里渲染子组件
        this.props.children
      }
    </div>)
  }
} 
像这样, 只要在需要渲染子组件的位置加上 this.props.children 那么子组件的内容就回渲染在 这是正常内容 的下面, 否则, 父组件是不会渲染子组件的内容的。
但是又有一个问题, 如果我们还想对子组件传参的话该怎么办呢?显然这样写的话是没办法实现的。
其中一种办法就是使用redux等状态管理插件来实现, 但是如果你的项目不是特别大的话, 无疑会搞得更复杂, 并且还会增加额外的学习成本。
所以我们可以用第二种方法: 使用React自带的React.Children和React.cloneElement这两个个Api。
借助React.Children, 我们可以这样做, 给子组件传递属性:
class Parent extends Component {
  render() {
    return (<div>
      <div>
        这是正常的内容
      </div>
      {
        // 返回子组件, 并传入你的属性
         React.Children.map(this.props.children,(child,i)=>{
           return React.cloneElement(child,{
             ...someProps
           })
         })
       }
    </div>)
  }
} 
看了上面的代码, React.Children能让我们对 props.children 进行遍历, 而React.cloneElement能让我们为遍历出来的child添加新的属性。
有的人可能会说: 我不使用React.Child, 直接对props.children使用map函数遍历照样可以啊。
是的, 在一些特殊情况下, 是可以直接对props.children使用map函数, 但那仅限于所有子元素都是组件的情况下, 因为从本质上来讲, props.children 可以使任何的类型,比如数组、函数、对象等等,
如果 props.children 不是数组, 那就gg了:
然而使用 React.Children.map 函数,无论是什么都不会报错。
所以我们要尽量使用React.Children来操作 props.children。
对于React.Children的详细理解可以参考。
