React之children的特殊用法

2020-07-23  本文已影响0人  雨落倾城夏微凉_e861

平常我们在react使用children的用法大多都是和vue的slot插槽那样去使用,但是react中的children还是有很多有趣的用法,我们写一些小的demo来看看。

在vue中预留位置插入dom可以用slot占位,而且vue中的slot还有一个特殊的功能是具名插槽。这个功能在react的children中就不具备了,如果非要用那就用一个自定义属性传过来效果也是一样的比如说:

function Comp1(){
  const header = <div>这是header</div>
  return <Comp2 header={header}></Comp2>
}
function Comp2( { header:Header } ){
  return Header
}
export default Comp1

展示效果如下:

1.png

不过平常我们开发时主要是这么用:

function Comp1(){
  return <Comp2><h1>这是Comp1组件</h1></Comp2>
}
function Comp2( props ){
  return <div>{props.children}</div>
}
export default Comp1
2.png

一样没问题。

那么如果我们把children当作一个函数呢代码修改如下:

const fn = {
  getInfo(){
    return {name: "react", total: "100000+"}
  }
}
function Comp1(){
  return (
    <Comp2 name="getInfo">
      {({name, total}) => (
        <div><p>框架:{name}</p><p>学习人数:{total}</p></div>
      )}
    </Comp2>
  )
}
function Comp2( {name, children} ){
  const info = fn[name]();
  return children(info)
}
export default Comp1

效果如下:


3.png

我们发现他也可以作为方法来执行。

接下来看下children的过滤效果:

function Comp1(){
  return (
    <Comp2 type="div">
      <div>1-div</div>
      <div>2-div</div>
      <p>3-p</p>
      <div>4-div</div>
      <p>5-p</p>
   </Comp2>
)}
function Comp2( props ){
  return (
    <div>{
     React.Children.map(props.children,child => {
          if(child.type == props.type){
            return child
          }
          return ""
      })}
  </div>
  )}
export default Comp1

展示效果如下:

4.png

最终我们过滤出所有的div展示出来。

接下来我们给children里面的组件添加属性

function Input({children, ...rest}){
  return <label htmlFor=""><input {...rest} type="checkbox" />{children}</label>
}
function InputGroup(props){
  return (
    <div>
      {
        React.Children.map(props.children, child => {
          return child.checked = true//直接给组件添加一个checked属性
        })
      }
    </div>
  )
}
function Addattr(){
  return (
    <InputGroup>
      <Input>体育</Input>
      <Input>财经</Input>
    </InputGroup>
  )
}
export default Addattr;

我们直接给组件添加一个checked属性,查看页面效果


5.png

发现报错了,react不允许我们这样直接添加属性,要解决这个问题需要用到react的一个方法React.cloneElement,我们修改一下我们的代码

function Input({children, ...rest}){
  return <label htmlFor=""><input {...rest} type="checkbox" />{children}</label>
}
function InputGroup(props){
  return (
    <div>
      {
        React.Children.map(props.children, child => {
          return React.cloneElement(child,{checked: true})//这次我们通过React.cloneElement添加属性
        })
      }
    </div>
  )
}
function Addattr(){
  return (
    <InputGroup>
      <Input>体育</Input>
      <Input>财经</Input>
    </InputGroup>
  )
}
export default Addattr;

查看页面效果

6.png
7.png

发现添加成功。

上一篇下一篇

猜你喜欢

热点阅读