- A+
所属分类:Web前端
原文链接: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 了
完结!撒花!