react-组件组合

react中除了一些基本的操作之外,还有一些纯组件,高阶组件,高阶组件链式调用,高阶组件装饰器写法,组合使用组件,等等

组合组件,类似于vue中slot
  • 最简单的用法,默认插槽
    import React, { Component } from 'react'
    
    function Dialog(props){
      return(
      <div style={{border: `1px solid ${props.color || 'blue'}`}}>
        {props.children}
      </div>
      )
    }
    
    function WelDialog(props){
      return(
        <Dialog {...props}>
          <h2>我是一个标题</h2>
          <p>啦啦啦啦啦</p>
        </Dialog>
      )
    }
    
    export default class ShowDialog extends Component {
      render() {
        return (
          <div>
            <WelDialog color='green'/>
          </div>
        )
      }
    }
    

    一个组件,肚子里的东西,可以通过props.children,来渲染,即通过props.children在dialog组件中占位,父组件传给我什么,我就显示什么。

  • 第二种,具名插槽使用
    import React, { Component } from 'react'
    
    function Dialog(props){
      return(
      <div style={{border: `1px solid ${props.color || 'blue'}`}}>
        {props.children}
        <div className="footer">
          {props.footer}
        </div>
      </div>
      )
    }
    
    function WelDialog(props){
      return(
        <Dialog {...props}>
          <h2>我是一个标题</h2>
          <p>啦啦啦啦啦</p>
        </Dialog>
      )
    }
    
    export default class ShowDialog extends Component {
      render() {
        const footer=<button onClick={()=>alert('按钮被点击')}>点击我试试</button>
        return (
          <div>
            <WelDialog color='green' footer={footer}/>
          </div>
        )
      }
    }
    
    

    命名的footer内容,渲染在了dialog中的footer部分,其他没有取名字的部分,默认都渲染在props.children位置处。

  • 类似作用域插槽
    import React, { Component } from 'react'
    
    const Api={
      getUser:()=>{
        return  {name:'jeery',age:20}
      }
    }
    
    function Fetcher(props){
      const user = Api[props.name]()
      return props.children(user)
    }
    
    export default class ShowDialog extends Component {
      render() {
        return (
          <div>
            <Fetcher name='getUser'>
              {({name, age})=>(<p>{name} ----{age}</p>)}
            </Fetcher>
          </div>
        )
      }
    }
    
    

    fetcher是一个子组件,父组件调用子组件时,想要使用子组件中的数据,类似于vue中的作用域插槽。其实就是,父组件想要使用fetcher组件中的数据,就是给fetcher组件中传入一个函数,可以在参数处,拿到数据,想要什么样的dom结构,就返回什么样的dom结构。

    fetcher组件中,调用接口拿到数据,这时,props.children就不是dom,而是父组件给我传进来的一个函数,所以我需要调用这个函数。

  • 另一种组合的高阶用法—过滤器组件,对父组件传递给我的东西进行过滤,使用react暴露出的静态方法,React.Children.map

    import React, { Component } from 'react'
    
    function Filter({children,type}){
      return(
        <div>
          {
            React.Children.map(children, (child)=>{
              if(child.type !== type){
                return
              }
              return child
            })
          }
        </div>
      )
    }
    
    export default class ShowDialog extends Component {
      render() {
        return (
          <div>
            <Filter type="p">
              <h2>vue</h2>
              <p>vue 很不错</p>
              <h2>react</h2>
              <p>react 很不错</p>
            </Filter>
          </div>
        )
      }
    }
    
  • 组合高阶使用二-----RadioGroup组件

    import React, { Component } from 'react'
    
    function Radio({children, ...rest}){
      return(
        <label>
          <input type="radio" {...rest}/>
          {children}
        </label>
      )
    }
    
    function RadioGroup(props){
      return(
        <div>
          {React.Children.map(props.children, child=>{
            return React.cloneElement(child, {name: props.name})
          })}
        </div>
      )
    }
    
    export default class ShowDialog extends Component {
      render() {
        return (
          <div>
            <RadioGroup name='mvvm'>
              <Radio value='vue'>vue</Radio>
              <Radio value='react'>react</Radio>
              <Radio value='angular'>angular</Radio>
            </RadioGroup>
          </div>
        )
      }
    }
    
    

    在使用radio时,需要命名一个组,通过给radio加name来定义为一个组,但是每个radio都加,比较麻烦,利用一下children,通过props.children,但是不能给child加props,在react中是不允许的,这里,react提供了一个React.cloneElement(children,{}),第一个参数是children,第二个参数是需要加的props,这样可以用的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值