我正在创建一个 React 组件库,并且我的库组件之一中有一个我想要导出的函数。 addParticle 函数旨在允许库的用户通过传递 props 动态地将粒子添加到容器中。这是我的组件的代码片段:
import React, { useState } from "react";
import Particle from "../Particle";
import "./ParticleContainer.css";
export interface AddParticleProps {
src: string;
height: string;
width: string;
animationDuration: number;
}
interface ParticleContainerProps {
height?: string;
width?: string;
position?: "relative" | "absolute";
}
function ParticleContainer({
height = "40px",
width = "40px",
position,
}: ParticleContainerProps) {
const [particleDetails, setParticleDetails] = useState<AddParticleProps[]>(
[]
);
const addParticle = ({
src,
height,
width,
animationDuration,
}: AddParticleProps) => {
setParticleDetails([
...particleDetails,
{ src, height, width, animationDuration },
]);
};
return (
<div className="particlesContainer" style={{ height, width, position }}>
{particleDetails.map((props, index) => {
return <Particle key={index} id={index} {...props} />;
})}
</div>
);
}
export { addParticle }; // How to properly export this function?
export default ParticleContainer;
您不能直接执行此操作。
addParticle
是 ParticleContainer
组件中的一个函数,无法从外部范围访问 - 并且您不能将其移到外部,因为它引用了组件内部必需的 setParticleDetails
函数(因为该函数是从 useState
返回的)
与所有 React hook 一样,只能从函数组件内部调用)。
您可以做的是导出一个自定义钩子来执行此操作,这对于 React 组件库来说是完全正常的和预期的。有几种方法可以设计 API,具体取决于您希望消费者能够使用您的库执行哪些操作,但作为基于您已经共享的内容的起点,我猜您想要返回一个对象(一个数组也可以工作,但我使用了下面的一个对象),其中包含所有渲染的 Particle
组件的 UI 和
addParticle
函数:function useParticles() {
const [particleDetails, setParticleDetails] = useState<AddParticleProps[]>(
[]
);
const addParticle = ({
src,
height,
width,
animationDuration,
}: AddParticleProps) => {
setParticleDetails([
...particleDetails,
{ src, height, width, animationDuration },
]);
};
const particles = particleDetails.map((props, index) => {
return <Particle key={index} id={index} {...props} />;
});
return { particles, addParticles };
};
一旦有了这个,消费者就可以轻松地重新创建您建议的
ParticleContainer
组件,如下所示:
function ParticleContainer({
height = "40px",
width = "40px",
position,
}: ParticleContainerProps) {
const { particles, addParticle } = useParticles();
return (
<div className="particlesContainer" style={{ height, width, position }}>
{particles}
</div>
);
}
其中
addParticles
函数当前未使用,但可以轻松地在组件内使用(例如,将其作为
onclick
处理程序传递给子组件中的某个按钮)。这也将渲染逻辑和添加“粒子”与容器组件的样式(宽度、高度和位置)分离 - ParticleContainer
,或消费者想要用于容器的任何替代方案,包含该信息,
useParticles
钩子负责添加粒子本身的逻辑。