实现React插槽功能,增强React的可组合性

123 阅读1分钟

前言

  • Vue开发一个组件的时候,它有一个插槽的功能,当一个组件不足我们的需要时,可以用一个插槽先占位,其他小伙伴可以自己扩展
  • React在开发一个组件的时候,它没有插槽的能力,于是自己决定手撸一个,让React也支持类似于Vue插槽

思路

  • 1、给ReactElement节点加一个slot的属性
  • 2、组件在渲染的时候通过 props.children获取到ReactElement子节点,并且转换成数组
  • 3、遍历获取到的ReactElement子节点,取出props中的slot作为对象的key,ReactElement作为对象的value
  • 4、在遍历的过程中,如果没有slot属性,default作为对象的key
  • 5、最终我们会得到一个完整的Map对象,去渲染到对应的容器中

完整代码

// 插槽hooks函数
const useSlot = (props) => {
  let childrens = [];
  if (props.children) {
    if (Array.isArray(props.children)) {
      childrens = props.children;
    } else {
      childrens = [props.children];
    }
  }
  let slotMap = {};
  childrens.forEach((children) => {
    slotMap[children.props.slot || "default"] = children;
  });
  return slotMap;
};
// 组件
function Layout(props) {
  const slot = useSlot(props);
  return (
    <>
      {slot.head}
      {slot.middle}
      {slot.tail}
      {slot.default}
    </>
  );
}

export default function AppSlot() {
  return (
    <>
      <Layout>
        <h1>默认</h1>
        <h1 slot="head">头部</h1>
        <h1 slot="middle">中间</h1>
        <h1 slot="tail">尾部</h1>
      </Layout>
    </>
  );
}

渲染截图

reactSolt.eaa2ac70.png