You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置Prettier让React组件中Hook按指定规则排序?

问题描述

我正在使用VSCode,当前的prettier.config.js配置如下:

// prettier.config.js
module.exports = {
  plugins: [require("prettier-plugin-tailwindcss")],
  printWidth: 80,
  tabWidth: 4,
  trailingComma: "all",
  singleQuote: true,
  semi: true,
  importOrder: ["^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"],
  importOrderSeparation: true,
  importOrderSortSpecifiers: true,
};

我的React组件代码片段如下:

...
import TextField from '@mui/material/TextField';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import * as yup from 'yup';

function ItemLinkScreen(props) {
    const router = useRouter();
    const { 'space-slug': spaceSlug, 'section-slug': sectionSlug } = router.query;

    const { mutate } = useSpace(spaceSlug);

    const [url, setUrl] = useState(null);
    const [framelyResponse, setFramelyResponse] = useState(null);
    const [framelyError, setFramelyError] = useState(null);
    const [dialogOpened, setDialogOpened] = useState(false);

    const schema = yup.object({
        name: yup.string().min(3).max(255).required(),
    });

    const {
        register,
        reset,
        formState: { errors },
        setFocus,
        handleSubmit,
        control,
    } = useForm({ resolver: yupResolver(schema) });
    const [apiErrors, setApiErrors] = useState([]);

    const onSubmit = async (data) => {
        
    };

    useEffect(() => {
        setFocus('name');
    }, [dialogOpened]);

    return (
        
    );
}

export default ItemLinkScreen;

当前组件里useState分散在代码中间,我希望通过Prettier配置实现以下代码排序规则:

  • useRouter置于组件最顶部
  • 所有useState集中在组件开头
  • useEffect放在return语句之前

请问该如何配置Prettier满足需求?

解决方案

要实现自定义的React Hooks排序,需要用到@trivago/prettier-plugin-sort-imports插件(该插件与你当前使用的prettier-plugin-tailwindcss兼容,但需调整插件顺序),并添加自定义的hooks排序规则。

步骤1:安装依赖

在项目中安装@trivago/prettier-plugin-sort-imports:

npm install @trivago/prettier-plugin-sort-imports --save-dev
# 或
yarn add @trivago/prettier-plugin-sort-imports --dev

步骤2:修改Prettier配置

更新prettier.config.js,添加hooks排序相关配置,同时注意插件顺序(prettier-plugin-tailwindcss要放在最后):

// prettier.config.js
module.exports = {
  plugins: [
    require("@trivago/prettier-plugin-sort-imports"),
    require("prettier-plugin-tailwindcss"),
  ],
  printWidth: 80,
  tabWidth: 4,
  trailingComma: "all",
  singleQuote: true,
  semi: true,
  // 保留原有导入排序配置
  importOrder: ["^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"],
  importOrderSeparation: true,
  importOrderSortSpecifiers: true,
  // 添加自定义hooks与变量排序规则
  customOrder: [
    // 第一组:useRouter声明
    "^const router = useRouter\\(\\)$",
    // 第二组:所有useState声明
    "^const \\[.*\\] = useState\\(.*\\)$",
    // 第三组:其他自定义/第三方hooks(如useSpace、useForm)
    "^const .* = use.*\\(.*\\)$",
    // 第四组:普通变量定义(如schema)
    "^const .* = .*$",
    // 第五组:函数定义(如onSubmit)
    "^const .* = async? \\(.*\\) =>$",
    "^function .*\\(.*\\)$",
    // 第六组:useEffect声明(放在return前)
    "^useEffect\\(.*\\)$",
  ],
  customOrderSeparation: true,
};

配置说明

  • customOrder:通过正则表达式定义变量和hooks的排序优先级,完全匹配你需要的结构顺序
  • customOrderSeparation:开启后,每组规则之间会自动添加空行,让代码结构更清晰
  • 插件顺序:@trivago/prettier-plugin-sort-imports必须放在prettier-plugin-tailwindcss之前,避免样式类排序出现异常

效果验证

配置完成后,保存组件代码时,Prettier会自动将代码调整为目标结构:

function ItemLinkScreen(props) {
    // 最顶部:useRouter
    const router = useRouter();
    const { 'space-slug': spaceSlug, 'section-slug': sectionSlug } = router.query;

    // 集中的useState
    const [url, setUrl] = useState(null);
    const [framelyResponse, setFramelyResponse] = useState(null);
    const [framelyError, setFramelyError] = useState(null);
    const [dialogOpened, setDialogOpened] = useState(false);
    const [apiErrors, setApiErrors] = useState([]);

    // 其他hooks
    const { mutate } = useSpace(spaceSlug);
    const {
        register,
        reset,
        formState: { errors },
        setFocus,
        handleSubmit,
        control,
    } = useForm({ resolver: yupResolver(schema) });

    // 普通变量
    const schema = yup.object({
        name: yup.string().min(3).max(255).required(),
    });

    // 函数定义
    const onSubmit = async (data) => {
        
    };

    // useEffect放在return之前
    useEffect(() => {
        setFocus('name');
    }, [dialogOpened]);

    return (
        
    );
}

内容的提问来源于stack exchange,提问作者Ali Gajani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:18:16