props.children

2020-01-24  本文已影响0人  soojade

简单的“插槽”

const Welcome = (props) => {
  return (
    <div>
     <p> Welcome to {props.addr}</p> // Welcome to china
      <p> Welcome to {props.children}</p> // Welcome to china
    </div>
  )
}

const App = () => {
  return (
    <Welcome addr='china'>
      china
    </Welcome>
  )
}

children可以是任何合法的 js 表达式

具名“插槽”

这里children是一个对象,children的属性就是具名的“插槽”

const Welcome = (props) => {
  return (
    <div>
      <h2>{props.title}</h2>           // Welcome
      <h3>{props.children.title}</h3> // Welcome
      <p>{props.children.body}</p>   // Welcome to china
    </div>
  )
}

const App = () => {
  return (
    <Welcome title='Welcome'>
      {{
        title: 'Welcome',
        body: 'Welcome to china'
      }}
    </Welcome>
  )
}

作用域“插槽”

children也可以是一个函数,通过给children`传参,传递作用域的属性。

const Welcome = (props) => {
  const message = {
    a: {
      name: 'aixi',
      age: 16
    },
    b: {
      name: 'lili',
      age: 18
    }
  }
  return (
    <div>
      {props.children(message[props.role])}
    </div>
  )
}

const App = () => {
  return (
    <Welcome role="b">
      {
        ({ name, age }) => {
          return (
            <p>name:{name},age:{age}</p>
          )
        }
      }
    </Welcome>
  )
}

修改children

假如传递给props.children的是组件,只能使用React.cloneElement(ar1,ar2)生成新的组件,参数1是要克隆的对象,参数2是要设置的属性。

const App = () => {
  return (
    <RadioGroup name="mvvm"> // 处理之后,只需要在这里设置name属性即可
      <Radio>react</Radio>
      <Radio>vue</Radio>
      <Radio>angular</Radio>
    </RadioGroup>
  )

}
const Radio = ({ children, ...rest }) => {
  return (
    <label>
      <input type="radio" {...rest} />{children}
    </label>
  )
}
const RadioGroup = (props) => {
  return (
    <div>
      {
         // 假如是 props.children 无法修改接收name属性
        React.Children.map(props.children, radio => {
          return React.cloneElement(radio, { name: props.name })
       })
      }
    </div>
  )
}
上一篇下一篇

猜你喜欢

热点阅读