7个技巧让你写出干净的 TSX 代码

  • 7个技巧让你写出干净的 TSX 代码已关闭评论
  • 189 次浏览
  • A+
所属分类:Web前端
摘要

原文链接:https://dev.to/ruppysuppy/7-tips-for-clean-react-typescript-code-you-must-know-2da2“干净的代码”不仅是可以正常运行的代码。它指的是组织整齐、易于阅读、易于理解且易于维护的代码。


原文链接:https://dev.to/ruppysuppy/7-tips-for-clean-react-typescript-code-you-must-know-2da2

“干净的代码”不仅是可以正常运行的代码。它指的是组织整齐易于阅读易于理解且易于维护的代码。

让我们来看看 React 中“干净代码”的一些最佳实践,它们可以让你更加轻松地维护代码!??

1. 为所有值提供显式类型

使用 TypeScript 时,很多人经常不为值提供显式类型,从而错失 TS 在开发中的真正用处

坏栗子 01:

const Component = ({ children }: any) => {   // ... }; 

坏栗子 02:

const Component = ({ children }: object) => {   // ... }; 

恰当地使用interface 能够让编辑器给你提供准确的提示,从而让敲代码变得更容易

好栗子:

import { ReactNode } from "react";  interface ComponentProps {   children: ReactNode; }  const Component = ({ children }: ComponentProps) => {   // ... }; 

2. 更新状态时考虑先前的状态

如果更新状态时新状态依赖于旧状态,在调用更新状态函数时传入函数来更新状态,React 状态更新会进行批处理,如果不使用这种方式更新状态很可能导致意想不到的结果

坏栗子:

import React, { useState } from "react";  export const App = () => {   const [isDisabled, setIsDisabled] = useState(false);    const toggleButton = () => {     setIsDisabled(!isDisabled);   };    // 此处调用两次toggleButton的结果和调用一次相同   const toggleButtonTwice = () => {     toggleButton();     toggleButton();   };    return (     <div>       <button disabled={isDisabled}>         I'm {isDisabled ? "disabled" : "enabled"}       </button>       <button onClick={toggleButton}>         Toggle button state       </button>       <button onClick={toggleButtonTwice}>         Toggle button state 2 times       </button>     </div>   ); }; 

好栗子:

import React, { useState } from "react";  export const App = () => {   const [isDisabled, setIsDisabled] = useState(false);    const toggleButton = () => {     setIsDisabled((isDisabled) => !isDisabled);   };    const toggleButtonTwice = () => {     toggleButton();     toggleButton();   };    return (     <div>       <button disabled={isDisabled}>         I'm {isDisabled ? "disabled" : "enabled"}       </button>       <button onClick={toggleButton}>         Toggle button state       </button>       <button onClick={toggleButtonTwice}>         Toggle button state 2 times       </button>     </div>   ); }; 

3. 保持文件原子性和精简性

保持稳健的原子性和精简性可以让调试、维护甚至查找文件更加容易

坏栗子:

// src/App.tsx export default function App() {   const posts = [     {       id: 1,       title: "How to write clean react code",     },     {       id: 2,       title: "Eat, sleep, code, repeat",     },   ];    return (     <main>       <nav>         <h1>App</h1>       </nav>       <ul>         {posts.map((post) => (           <li key={post.id}>             {post.title}           </li>         ))}       </ul>     </main>   ); } 

好栗子:

// src/App.tsx export default function App() {   return (     <main>       <Navigation title="App" />       <Posts />     </main>   ); }  // src/components/Navigation.tsx interface NavigationProps {   title: string; }  export default function Navigation({ title }: NavigationProps) {   return (     <nav>       <h1>{title}</h1>     </nav>   ); }  // src/components/Posts.tsx export default function Posts() {   const posts = [     {       id: 1,       title: "How to write clean react code",     },     {       id: 2,       title: "Eat, sleep, code, repeat",     },   ];    return (     <ul>       {posts.map((post) => (         <Post key={post.id} title={post.title} />       ))}     </ul>   ); }  // src/components/Post.tsx interface PostProps {   title: string; }  export default function Post({ title }: PostProps) {   return <li>{title}</li>; } 

4. 对具有多个状态的值使用枚举或常量对象

使用枚举或常量对象可以大大简化管理存在多种状态的变量的过程

坏栗子:

import React, { useState } from "react";  export const App = () => {   const [status, setStatus] = useState("Pending");    return (     <div>       <p>{status}</p>       <button onClick={() => setStatus("Pending")}>         Pending       </button>       <button onClick={() => setStatus("Success")}>         Success       </button>       <button onClick={() => setStatus("Error")}>         Error       </button>     </div>   ); } 

好栗子:

import React, { useState } from "react";  enum Status {   Pending = "Pending",   Success = "Success",   Error = "Error", } // OR // const Status = { //   Pending: "Pending", //   Success: "Success", //   Error: "Error", // } as const;  export const App = () => {   const [status, setStatus] = useState(Status.Pending);    return (     <div>       <p>{status}</p>       <button onClick={() => setStatus(Status.Pending)}>         Pending       </button>       <button onClick={() => setStatus(Status.Success)}>         Success       </button>       <button onClick={() => setStatus(Status.Error)}>         Error       </button>     </div>   ); }; 

5. 尽量不在视图中编写逻辑

尽量不要把逻辑代码嵌入到标签中

坏栗子:

const App = () => {   return (     <div>       <button         onClick={() => {           // ...         }}       >         Toggle Dark Mode       </button>     </div>   ); }; 

好栗子:

const App = () => {   const handleDarkModeToggle = () => {     // ...   };    return (     <div>       <button onClick={handleDarkModeToggle}>         Toggle Dark Mode       </button>     </div>   ); }; 

当然如果逻辑代码只有简单的一行,写在标签中也是可以的

6. 正确地选择条件渲染的方式

正确地选择条件渲染的方式可以让代码更优雅

坏栗子:

const App = () => {   const [isTextShown, setIsTextShown] = useState(false);    const handleToggleText = () => {     setIsTextShown((isTextShown) => !isTextShown);   };    return (     <div>       {isTextShown ? <p>Now You See Me</p> : null}        {isTextShown && <p>`isTextShown` is true</p>}       {!isTextShown && <p>`isTextShown` is false</p>}        <button onClick={handleToggleText}>Toggle</button>     </div>   ); }; 

好栗子:

const App = () => {   const [isTextShown, setIsTextShown] = useState(false);    const handleToggleText = () => {     setIsTextShown((isTextShown) => !isTextShown);   };    return (     <div>       {isTextShown && <p>Now You See Me</p>}        {isTextShown ? (         <p>`isTextShown` is true</p>       ) : (         <p>`isTextShown` is false</p>       )}        <button onClick={handleToggleText}>Toggle</button>     </div>   ); }; 

7. 使用JSX简写

布尔属性

一个具有真值的属性可以只写属性名,比如truthyProp,而不必写成truthyProp={true}

坏栗子:

interface TextFieldProps {   fullWidth: boolean; }  const TextField = ({ fullWidth }: TextFieldProps) => {   // ... };  const App = () => {   return <TextField fullWidth={true} />; }; 

好栗子:

interface TextFieldProps {   fullWidth: boolean; }  const TextField = ({ fullWidth }: TextFieldProps) => {   // ... };  const App = () => {   return <TextField fullWidth />; }; 

字符串属性

属性值为字符串字面量可以直接用双引号包裹

坏栗子:

interface AvatarProps {   username: string; }  const Avatar = ({ username }: AvatarProps) => {   // ... };  const Profile = () => {   return <Avatar username={"John Wick"} />; }; 

好栗子:

interface AvatarProps {   username: string; }  const Avatar = ({ username }: AvatarProps) => {   // ... };  const Profile = () => {   return <Avatar username="John Wick" />; }; 

Undefined 属性

和普通的TS/JS一样,如果属性未提供值,则为undefined

坏栗子:

interface AvatarProps {   username?: string; }  const Avatar = ({ username }: AvatarProps) => {   // ... };  const Profile = () => {   return <Avatar username={undefined} />; }; 

好栗子:

interface AvatarProps {   username?: string;   // OR `username: string | undefined` }  const Avatar = ({ username }: AvatarProps) => {   // ... };  const Profile = () => {   return <Avatar />; }; 

现在你应该知道怎么编写干净的 TSX 了

完结!撒花!

7个技巧让你写出干净的 TSX 代码