如何设计更优雅的 React 组件?( 二 )


(1)常量定义组件中的所有 magic 值,例如字符串或者数字 , 都应该放在文件的顶部,导入依赖项的下方 。由于这些都是静态常量,这意味着它们的值不会改变 。因此将它们放在组件中是没有意义的,因为放在组件中的话 , 它们会在每次重新渲染组件时重新创建 。
const MAX_READING_TIME = 10;const META_TITLE = "Hello World";对于更复杂的静态数据结构,可以将其提取到一个单独的文件中,以保持组件代码整洁 。
(2)类型定义下面是使用 TypeScript 声明的组件 props 的类型:
interface Props {  id: number;  name: string;  title: string;  meta: Metadata;}如果这个 props 的类型不需要导出 , 可以使用 Props 作为接口名称 , 这样可以帮助我们立即识别组件 props 的类型定义,并将其与其他类型区分开 。
只有当这个 Props 类型需要在多个组件中使用时,才需要添加组件名称,例如ButtonProps,因为它在导入另一个组件时,不应该与另一个组件的Props类型冲突 。
3. 组件定义定义函数组件的方式有两种:函数声明和箭头函数, 推荐使用函数声明的形式,因为这就是语法声明的内容:函数 。官方文档的示例中也使用了这种方法:
function Article(props: Props) {  /**/}只会在必须使用 forwardRef 时才使用箭头函数:
const Article = React.forwardRef<htmlArticleElement, Props>(  (props, ref) => {    /**/  });通常会在组件最后默认导出组件:
export default Article;4. 变量声明接下来 , 我们就需要在组件里面进行变量的声明 。注意 , 即使使用 const 声明 , 这里也称为变量 , 因为它们的值通常会在不同的渲染之间发生变化,只有在执行单个渲染过程时是恒定的 。
const { id, name, title } = props;const router = useRouter();const initials = getInitials(name);这里通常包含在组件级别使用的所有变量,使用 const 或 let 定义,具体取决于它们在渲染期间是否更改其值:

  • 解构数据:通常来自 props、数据 stores 或组件的 state
  • Hooks:自定义hooks、框架内置 Hooks,例如 useStateuseReduceruseRefuseCallback 或 useMemo
  • 在整个组件中使用的已处理数据,由函数计算得出;
一些较大的组件可能需要在组件中声明很多变量 。这种情况下 , 建议根据它们的初始化方法或者用途对它们进行分组:
// 框架 hooksconst router = useRouter();// 自定义 hooksconst user = useLoggedUser();const theme = useTheme();// 从 props 中解构的数据const { id, title, meta, content, onSubscribe, tags } = props;const { image, author, date } = meta;// 组件状态const [emAIl, setEmail] = React.useState("");const [showMenu, toggleMenu] = React.useState(false);const [activeTag, dispatch] = React.useReducer(reducer, tags);// 记忆数据const subscribe = React.useCallback(onSubscribe, [id]);const summary = React.useMemo(() => getSummary(content), [content]);// refsconst sideMenuRef = useRef<HTMLDivElement>(null);const subscribeRef = useRef<HTMLButtonElement>(null);// 计算数据const initials = getInitials(author);const formattedDate = getDate(date);变量分组的方法在不同组件之间可能会存在很大的差异,它取决于变量的数量和类型 。关键是要将相关变量放在一起,在不同组之间添加一个空行来提高代码的可读性 。
注:上面代码中的注释仅用于标注分组类型,在实际项目中不会写这些注释 。
5. EffectsEffects 部分通常会写在变量声明之后,它们可能是React中最复杂的构造,但从语法的角度来看它们非常简单:


推荐阅读