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,这样可以用的