ソース情報
- リポジトリ
- canwhite/Krebs
- ソースの最終更新活動
- 2026年6月7日 05:36
- 検出された SKILL.md の言語
- 中国語
- スター
- 1,104
- フォーク
- 3
インストール方法
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
ソースファイルを確認
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
メニュー
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/canwhite/Krebs --skill no-useeffectコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
SKILL.md を表示中
SOC 職業分類に基づく
| 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,用上述替代模式替代。