بنقرة واحدة
no-useeffect
React 无 useEffect 编码规范 - 禁止直接使用 useEffect,使用替代模式代替
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
React 无 useEffect 编码规范 - 禁止直接使用 useEffect,使用替代模式代替
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
提供网页搜索功能示例,演示如何使用 curl 进行 HTTP 请求。用于学习如何构建包含 scripts 和 references 的标准 skill 结构。
基于"扩散模型叙事去噪流"的小说写作 SOP。将 AI 视为去杂质机器,通过锁定全局信号、预测叙事噪声、精准去噪、随机修正四个步骤,解决 AI 翻译腔、逻辑断层和故事平淡的问题。
ATS简历优化器 - 根据职位描述(JD)和个人能力,生成符合ATS解析要求的高匹配简历
Simple, plain language communication. No jargon overload. Clear explanations for everyone. Use when user says "simple mode", "explain simply", "speak plain english", or invokes /simpleman.
专业微信公众号爆款文章创作,基于痛点情绪故事在前、结论功能在后的原则,提供完整的文章结构、标题、开头、结尾生成方案
| name | no-useEffect |
| description | React 无 useEffect 编码规范 - 禁止直接使用 useEffect,使用替代模式代替 |
| category | coding |
| emoji | 🚫 |
| tags | ["react","useEffect","hooks","frontend","best-practice"] |
禁止直接调用 useEffect。对于需要与外部系统同步的罕见情况,使用 useMountEffect()。
export function useMountEffect(effect: () => void | (() => void)) {
/* eslint-disable no-restricted-syntax */
useEffect(effect, []);
}
大多数设置其他状态 的 effect 是不必要的,会增加额外的渲染。
// ❌ 差:两次渲染周期 - 先是过滤后的,后是过滤前的
function ProductList() {
const [products, setProducts] = useState([]);
const [filteredProducts, setFilteredProducts] = useState([]);
useEffect(() => {
setFilteredProducts(products.filter((p) => p.inStock));
}, [products]);
}
// ✅ 好:一次渲染中计算
function ProductList() {
const [products, setProducts] = useState([]);
const filteredProducts = products.filter((p) => p.inStock);
}
警惕信号:
useEffect(() => setX(deriveFromY(y)), [y])基于 effect 的获取经常产生竞态条件和重复的缓存逻辑。
// ❌ 差:竞态条件风险
function ProductPage({ productId }) {
const [product, setProduct] = useState(null);
useEffect(() => {
fetchProduct(productId).then(setProduct);
}, [productId]);
}
// ✅ 好:查询库处理取消/缓存/陈旧
function ProductPage({ productId }) {
const { data: product } = useQuery(["product", productId], () =>
fetchProduct(productId),
);
}
警惕信号:
fetch(...) 然后 setState(...)如果用户点击按钮,在处理器中做工作。
// ❌ 差:Effect 作为动作中转
function LikeButton() {
const [liked, setLiked] = useState(false);
useEffect(() => {
if (liked) {
postLike();
setLiked(false);
}
}, [liked]);
return <button onClick={() => setLiked(true)}>Like</button>;
}
// ✅ 好:直接的事件驱动动作
function LikeButton() {
return <button onClick={() => postLike()}>Like</button>;
}
警惕信号:
useMountEffect 只是在命名 hook 中包装的 useEffect(..., []),以使意图明确。
function useMountEffect(callback: () => void | (() => void)) {
useEffect(callback, []);
}
适用场景:
条件挂载的好模式:
// ❌ 差:在 effect 内部守卫
function VideoPlayer({ isLoading }) {
useEffect(() => {
if (!isLoading) playVideo();
}, [isLoading]);
}
// ✅ 好:当前置条件满足时才挂载
function VideoPlayerWrapper({ isLoading }) {
if (isLoading) return <LoadingScreen />;
return <VideoPlayer />;
}
function VideoPlayer() {
useMountEffect(() => playVideo());
}
警惕信号:
// ❌ 差:Effect 尝试模拟重新挂载行为
function VideoPlayer({ videoId }) {
useEffect(() => {
loadVideo(videoId);
}, [videoId]);
}
// ✅ 好:key 强制干净的重挂载
function VideoPlayer({ videoId }) {
useMountEffect(() => {
loadVideo(videoId);
});
}
function VideoPlayerWrapper({ videoId }) {
return <VideoPlayer key={videoId} videoId={videoId} />;
}
警惕信号:
在写 React 组件时,始终检查:
useEffectuseMountEffectkey 而非依赖 effect没有团队是零 bug 的。问题是想要哪种失败模式:
使用说明:当编写 React 组件代码时,始终遵循此规范。禁止直接使用 useEffect,用上述替代模式替代。