欢迎大家收看姊妹篇

​苍天祝我:利用prop来理解vue的v-slot2 赞同 · 0 评论文章正在上传…重新上传取消​

现在有这样一个组件,是用来切换一个​​<h1>​​的显示与隐藏

// Toggle.js
import React, { useState } from "react";
export const Toggle = props => {
const [on, setOn] = useState(false);
const toggle = () => setOn(prev => !prev);
return (
<div>
{on && <h1>{props.children}</h1>}
<button onClick={toggle}>Show/Hide</button>
</div>
);
};
// App.js
<div>
<Toggle>
Hello World
</Toggle>
</div>

很简单对吧,可是这样就不能重用了,只能切换显示这个​​<h1>​​​,而且也只能点击这个​​button​​来显示隐藏。

那如果能把on和toggle这两个API传到父组件就好了,子组件在里面用。子组件提供食材,父组件随便怎么玩。那么render prop应运而生。

首先得知道函数组件,除了通过​​jsx​​还可以通过直接调用的方式来渲染。

function Render = ({on, toggle}) => {
return (
<div>Hello World</div>
)
}
// 1. 函数调用
Render({ on, toggle }) // props通过对象来传
// 2. jsx方式
<Render on={on} toggle={toggle} />

然后我们稍微改造一下代码

// ToggleRenderProps.js
import React, { useState } from "react";
export const ToggleRenderProps = props => {
const [on, setOn] = useState(false);
const toggle = () => setOn(prev => !prev);
const {Render} = props
return (
<div>
{Render({
on,
toggle
})}
<Render on={on} toggle={toggle}/>
</div>
);
};
// App.js
const Child = ({ on, toggle }) => (
<>
{on && <nav>Nav</nav>}
<div onClick={toggle}>click me</div>
</>
)
<div>
<Toggle
Render={Child}
/>;
</div>

其实就是​​Render​​​传了一个函数组件,然后子组件拿到这个函数组件,渲染这个函数组件,渲染的就是Child里return的​​jsx​​​。这就是为什么这种模式叫​​render props​​​,通过一个名为​​render​​​的​​prop​​​传一个函数给子组件,叫子组件来渲染这个函数,至于叫不叫​​render​​​那随便。而Child这个组件里​​on​​​和​​toggle​​​是哪里来的,就可以理解为子组件给的食材,我利用这个食材想生成什么​​jsx​​​就生成什么​​jsx​​。

再改造一下

这样写起来还是有点不爽,在prop里传一个函数,能不能更直观一点呢,可以利用react自带的​​props.children​​属性。上面的代码我们还得显示地传这个props.xxx,不过react自带了一个props.children。

之前是​​props.render=一个函数组件​​​,现在改造成​​props.children=一个函数组件​

// ToggleRPC.js
import React, { useState } from "react";
export const ToggleRPC = props => {
const [on, setOn] = useState(false);
const toggle = () => setOn(prev => !prev);
const { children } = props;
return children({
on,
toggle
});
};
// App.js
export default function App() {
return (
<div className="App">
<ToggleRPC>
{({on, toggle})=>(
<div>
{on &&
<h1>Show Me</h1>}
<button onClick={toggle}>Show / Hide</button>
</div>
)}
</ToggleRPC>
</div>
);
}

可以看到只是从​​props.render=一个函数组件​​​变成了​​props.children=一个函数组件​​,代码就清爽了许多