简单的“插槽”
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>
)
}