ホームページ > 記事 > ウェブフロントエンド > よりクリーンな React コードを書くための 10 の実践的なヒント
この記事では、よりシンプルな React コードを作成するための 10 の実践的なヒントを紹介します。お役に立てば幸いです。
指定された props に true 値を渡すにはどうすればよいですか? [関連する推奨事項: Redis ビデオ チュートリアル 、プログラミング ビデオ ]
次の例では、prop showTitle
を使用してナビゲーション バー コンポーネントに表示します。アプリのタイトル:
export default function App() { return ( <main> <Navbar showTitle={true} /> </main> ); } function Navbar({ showTitle }) { return ( <div> {showTitle && <h1>标题</h1>} </div> ) }
ここで、showTitle
はブール値 true
に明示的に設定されていますが、コンポーネント prop で任意の
が提供されているため、これは必要ありません。すべてのデフォルト値は true
です。したがって、コンポーネントを呼び出すときに showTitle
を渡すだけで済みます。
export default function App() { return ( <main> <Navbar showTitle /> </main> ); } function Navbar({ showTitle }) { return ( <div> {showTitle && <h1>标题</h1>} </div> ) }
さらに、文字列を props
として渡す必要がある場合は、次のようにする必要はありません。中括弧を使用します{}
折り返し、文字列の内容を二重引用符で囲んで渡すことができます:
export default function App() { return ( <main> <Navbar title="标题" /> </main> ); } function Navbar({ title }) { return ( <div> <h1>{title}</h1> </div> ) }
よりクリーンな React コードを記述する最も簡単で最も重要な方法は、コードを個別の React コンポーネントに抽象化する方法を習得することです。
以下の例を見てみましょう。アプリケーションの上部にナビゲーション バーがあり、posts
内のデータが走査されて記事のタイトルが表示されます:
export default function App() { const posts = [ { id: 1, title: "标题1" }, { id: 2, title: "标题2" } ]; return ( <main> <Navbar title="大标题" /> <ul> {posts.map(post => ( <li key={post.id}> {post.title} </li> ))} </ul> </main> ); } function Navbar({ title }) { return ( <div> <h1>{title}</h1> </div> ); }
それで、何をすればいいでしょうか?このコードをよりきれいにするにはどうすればよいでしょうか?ループ内のコード (投稿タイトル) を別のコンポーネントに抽象化し、それを FeaturedPosts
と呼ぶことができます。抽出されたコードは次のとおりです。
export default function App() { return ( <main> <Navbar title="大标题" /> <FeaturedPosts /> </main> ); } function Navbar({ title }) { return ( <div> <h1>{title}</h1> </div> ); } function FeaturedPosts() { const posts = [ { id: 1, title: "标题1" }, { id: 2, title: "标题2" } ]; return ( <ul> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> ); }
ご覧のとおり、App コンポーネントでは、コンポーネント名 Navbar
および FeaturedPosts
を通じて、内容をすぐに確認できます。アプリはそうします。
上記の例では、3 つのコンポーネントを 1 つのファイルに実装しました。コンポーネントのロジックが小さい場合は問題なく記述できますが、コンポーネントのロジックが複雑になると、このように記述されたコードの可読性が非常に悪くなります。アプリファイルを読みやすくするために、各コンポーネントを別個のファイルに入れることができます。
これは、アプリケーション内の懸念事項を分離するのに役立ちます。これは、各ファイルが 1 つのコンポーネントのみを担当し、アプリで再利用する場合にコンポーネントのソースを難読化しないことを意味します。
// src/App.js import Navbar from './components/Navbar.js'; import FeaturedPosts from './components/FeaturedPosts.js'; export default function App() { return ( <main> <Navbar title="大标题" /> <FeaturedPosts /> </main> ); }
// src/components/Navbar.js export default function Navbar({ title }) { return ( <div> <h1>{title}</h1> </div> ); }
// src/components/FeaturedPosts.js export default function FeaturedPosts() { const posts = [ { id: 1, title: "标题1" }, { id: 2, title: "标题2" } ]; return ( <ul> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> ); }
さらに、各コンポーネントを独自のコンポーネントに含めることで、 file 。ファイルが肥大化しすぎないようにします。
FeaturedPosts コンポーネントで、偽のデータを使用する代わりに API から記事データを取得するとします。これを実現するには、フェッチ API を使用できます。
import React from 'react'; export default function FeaturedPosts() { const [posts, setPosts] = React.useState([]); React.useEffect(() => { fetch('https://jsonplaceholder.typicode.com/posts') .then(res => res.json()) .then(data => setPosts(data)); }, []); return ( <ul> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> ); }
しかし、複数のコンポーネントに対してこのデータ リクエストを実行したい場合はどうすればよいでしょうか?
FeaturedPosts コンポーネントに加えて、同じデータを含む Posts という名前の別のコンポーネントがあるとします。データを取得するロジックをコピーして、コンポーネントに貼り付ける必要があります。コードの重複を避けるために、useFetchPosts を呼び出すことができる新しい React フックを定義できます:
import React from 'react'; export default function useFetchPosts() { const [posts, setPosts] = React.useState([]); React.useEffect(() => { fetch('https://jsonplaceholder.typicode.com/posts') .then(res => res.json()) .then(data => setPosts(data)); }, []); return posts; }
これにより、FeaturedPosts コンポーネントを含む任意のコンポーネントで再利用できます:
import useFetchPosts from '../hooks/useFetchPosts.js'; export default function FeaturedPosts() { const posts = useFetchPosts() return ( <ul> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> ); }
コンポーネントを簡素化するもう 1 つの方法は、JSX から可能な限り多くの JavaScript を削除することです。次の例を見てください:
import useFetchPosts from '../hooks/useFetchPosts.js'; export default function FeaturedPosts() { const posts = useFetchPosts() return ( <ul> {posts.map((post) => ( <li onClick={event => { console.log(event.target, 'clicked!'); }} key={post.id}>{post.title}</li> ))} </ul> ); }
ここでは、記事のクリック イベントを処理しようとしていますが、JSX が読みにくくなっていることがわかります。この関数がインライン関数として含まれていると、このコンポーネントとその関連関数の目的がわかりにくくなります。
この問題を解決するにはどうすればよいですか? onClick を含むインライン関数を別のハンドラー関数に抽出し、それに handlePostClick という名前を付けることができます。このようにして、JSX の可読性が向上します:
import useFetchPosts from '../hooks/useFetchPosts.js'; export default function FeaturedPosts() { const posts = useFetchPosts() function handlePostClick(event) { console.log(event.target, 'clicked!'); } return ( <ul> {posts.map((post) => ( <li onClick={handlePostClick} key={post.id}>{post.title}</li> ))} </ul> ); }
JSX でインライン スタイルを書きすぎると、コードが読みにくくなります。
export default function App() { return ( <main style={{ textAlign: 'center' }}> <Navbar title="大标题" /> </main> ); } function Navbar({ title }) { return ( <div style={{ marginTop: '20px' }}> <h1 style={{ fontWeight: 'bold' }}>{title}</h1> </div> ) }
可能な限りインライン スタイルを CSS スタイルシートに移動したいと考えています。または、それらをオブジェクトに整理します:
export default function App() { const styles = { main: { textAlign: "center" } }; return ( <main style={styles.main}> <Navbar title="大标题" /> </main> ); } function Navbar({ title }) { const styles = { div: { marginTop: "20px" }, h1: { fontWeight: "bold" } }; return ( <div style={styles.div}> <h1 style={styles.h1}>{title}</h1> </div> ); }
一般に、これらのスタイルを CSS スタイル シートに記述するのが最善です。スタイルを動的に生成する必要がある場合は、オブジェクトで定義できます。
JavaScript では、オブジェクトのプロパティにアクセスする前に、まずオブジェクトが存在することを確認する必要があります。オブジェクトの値が未定義または null の場合、型エラーが発生します。
ユーザーが公開された投稿を編集できる例を見てみましょう。 EditButton コンポーネントは、isPostAuthor が true の場合、つまり認証されたユーザーの ID が投稿作成者の ID と同じ場合にのみ表示されます。
export default function EditButton({ post }) { const user = useAuthUser(); const isPostAuthor = post.author.userId !== user && user.userId; return isPostAuthor ? <EditButton /> : null; }
这段代码的问题是 user 可能是 undefined. 这就是为什么我们必须在尝试获取 userId 属性之前使用 && 运算符来确保 user 是一个对象。如果我要访问一个对象中的另一个对象,就不得不再包含一个 && 条件。 这会导致代码变得复杂、难以理解。
JavaScript 可选链运算符(?.)允许我们在访问属性之前检查对象是否存在。用它来简化上面的代码:
export default function EditButton({ post }) { const user = useAuthUser(); const isPostAuthor = post.author.userId !== user?.userId; return isPostAuthor ? <EditButton /> : null; }
这样将防止任何类型错误,并允许我们编写更清晰的条件逻辑。
在 React 应用中可以使用 function 关键字的函数声明语法编写组件,也可以使用设置为变量的箭头函数。使用 function 关键字的组件必须在返回任何 JSX 之前使用 return 关键字。
export default function App() { return ( <Layout> <Routes /> </Layout> ); }
通过将返回的代码包裹在一组括号中,可以通过隐式返回(不使用 return 关键字)从函数返回多行 JavaScript 代码。
对于使用箭头函数的组件,不需要包含 return 关键字,可以只返回带有一组括号的 JSX。
const App = () => ( <Layout> <Routes /> </Layout> ); export default App;
此外,当使用 .map()
迭代元素列表时,还可以跳过 return
关键字并仅在内部函数的主体中使用一组括号返回 JSX。
function PostList() { const posts = usePostData(); return posts.map(post => ( <PostListItem key={post.id} post={post} /> )) }
在 JavaScript 中,如果某个值是假值(如 null、undefined、0、''、NaN),可以使用 || 条件来提供一个备用值。
例如,在产品页面组件需要显示给定产品的价格,可以使用 || 来有条件地显示价格或显示文本“产品不可用”。
export default function ProductPage({ product }) { return ( <> <ProductDetails /> <span> {product.price || "产品不可用"} </span> </> ); }
现有的代码存在一个问题,如果商品的价格为0,也不会显示产品的价格而显示"产品不可用"。如果左侧为null
或者undefined
,而不是其他假值,就需要一个更精确的运算符来仅返回表达式的右侧。
这时就可以使用空值合并运算符,当左侧操作数为null或者 undefined 时,将返回右侧操作数。 否则它将返回其左侧操作数:
null ?? 'callback'; // "callback" 0 ?? 42; // 0
可以使用空值合并运算符来修复上面代码中的问题:
export default function ProductPage({ product }) { return ( <> <ProductDetails /> <span>{product.price ?? "产品不可用"} </> ); }
在 React 组件中编写条件时,三元表达式是必不可少的,经常用于显示或隐藏组件和元素。
当然,我们用可以使用三元表达式和模板字符串来给 React 元素动态添加或删除类名。
export default function App() { const { isDarkMode } = useDarkMode(); return ( <main className={`body ${isDarkMode ? "body-dark" : "body-light"}`}> <Routes /> </main> ); }
这种条件逻辑也可以应用于任何 props:
export default function App() { const { isMobile } = useDeviceDetect(); return ( <Layout height={isMobile ? '100vh' : '80vh'}> <Routes /> </Layout> ); }
【推荐学习:javascript视频教程】
以上がよりクリーンな React コードを書くための 10 の実践的なヒントの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。