平常我们在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
展示效果如下:

不过平常我们开发时主要是这么用:
function Comp1(){
return <Comp2><h1>这是Comp1组件</h1></Comp2>
}
function Comp2( props ){
return <div>{props.children}</div>
}
export default Comp1

一样没问题。
那么如果我们把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
效果如下:

我们发现他也可以作为方法来执行。
接下来看下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
展示效果如下:

最终我们过滤出所有的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属性,查看页面效果

发现报错了,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;
查看页面效果


发现添加成功。
网友评论