Maison > interface Web > js tutoriel > 10 conseils pratiques pour écrire du code React plus propre

10 conseils pratiques pour écrire du code React plus propre

青灯夜游
Libérer: 2023-01-03 20:18:51
avant
1733 Les gens l'ont consulté

Cet article compile et partage 10 conseils pratiques pour écrire du code React plus simple. J'espère qu'il sera utile à tout le monde !

10 conseils pratiques pour écrire du code React plus propre

1. Abréviation JSX

Comment transmettre la vraie valeur aux accessoires donnés ? [Recommandations associées : Tutoriel vidéo Redis, Vidéo de programmation]

Dans l'exemple suivant, utilisez la prop showTitle pour afficher le titre de l'application dans le composant de la barre de navigation : showTitle 在导航栏组件中显示应用的标题:

export default function App() {
  return (
    <main>
    <Navbar showTitle={true} />
  </main>
);
}

function Navbar({ showTitle }) {
  return (
    <div>
      {showTitle && <h1>标题</h1>}
    </div>
  )
}
Copier après la connexion

这里将 showTitle 显式设置为布尔值 true,其实这是没必要的,因为组件上提供的任何 prop 都具有默认值 true。因此只需要在调用组件时传递一个 showTitle 即可:

export default function App() {
  return (
    <main>
      <Navbar showTitle />
    </main>
  );
}

function Navbar({ showTitle }) {
  return (
    <div>
      {showTitle && <h1>标题</h1>}
    </div>
  )
}
Copier après la connexion

另外,当需要传递一个字符串作为 props 时,无需使用花括号 {} 包裹,可以通过双引号包裹字符串内容并传递即可:

export default function App() {
  return (
    <main>
      <Navbar title="标题" />
    </main>
  );
}

function Navbar({ title }) {
  return (
    <div>
      <h1>{title}</h1>
    </div>
  )
}
Copier après la connexion

2. 将不相关代码移动到单独的组件中

编写更简洁的 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>
  );
}
Copier après la connexion

那我们怎样才能让这段代码更加清洁呢?我们可以抽象循环中的代码(文章标题),将它们抽离到一个单独的组件中,称之为 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>
  );
}
Copier après la connexion

如你所见,在 App 组件中,通过其中的组件名称:NavbarFeaturedPosts

// src/App.js
import Navbar from &#39;./components/Navbar.js&#39;;
import FeaturedPosts from &#39;./components/FeaturedPosts.js&#39;;

export default function App() {
  return (
    <main>
      <Navbar title="大标题" />
      <FeaturedPosts />
    </main>
  );
}
Copier après la connexion

Ici be showTitle est explicitement défini sur une valeur booléenne true, ce qui n'est pas nécessaire puisque tout prop fourni sur le composant a une valeur par défaut de vrai . Il vous suffit donc de passer un showTitle lors de l'appel du composant :

// src/components/Navbar.js
export default function Navbar({ title }) {
  return (
    <div>
      <h1>{title}</h1>
    </div>
  );
}
Copier après la connexion
De plus, lorsque vous devez passer une chaîne en tant que props, il n'est pas nécessaire d'utiliser curl accolades { }, vous pouvez placer le contenu de la chaîne entre guillemets doubles et le transmettre :
// 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>
  );
}
Copier après la connexion

2 Déplacer le code non pertinent vers un composant séparé

.

Le moyen le plus simple et le plus important d'écrire du code React plus propre est de maîtriser l'abstraction de votre code en composants React distincts.

Regardons un exemple. Il y aura une barre de navigation en haut de l'application, et les données dans les posts seront parcourues pour afficher le titre de l'article :

import React from &#39;react&#39;;

export default function FeaturedPosts() {
  const [posts, setPosts] = React.useState([]); 	
    
  React.useEffect(() => {
    fetch(&#39;https://jsonplaceholder.typicode.com/posts&#39;)
      .then(res => res.json())
      .then(data => setPosts(data));
  }, []);

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}
Copier après la connexion

Alors, comment pouvons-nous faire ce code nettoyant ? Nous pouvons résumer le code dans la boucle (titres des articles) et les extraire dans un composant séparé, appelez-le FeaturedPosts. Le code extrait est le suivant :
import React from &#39;react&#39;;

export default function useFetchPosts() {
  const [posts, setPosts] = React.useState([]); 	
    
  React.useEffect(() => {
    fetch(&#39;https://jsonplaceholder.typicode.com/posts&#39;)
      .then(res => res.json())
      .then(data => setPosts(data));
  }, []);

  return posts;
}
Copier après la connexion
Comme vous pouvez le voir, dans le composant App, vous pouvez le voir rapidement à travers les noms des composants : Navbar et FeaturedPosts Le rôle de la demande.

3. Créez des fichiers séparés pour chaque composant

Dans l'exemple ci-dessus, nous avons implémenté trois composants dans un seul fichier. Si la logique des composants est petite, il n'y a aucun problème à les écrire. Cependant, si la logique des composants est plus complexe, la lisibilité du code écrit de cette manière sera très mauvaise. Pour rendre les fichiers de votre application plus lisibles, vous pouvez placer chaque composant dans un fichier distinct.

Cela nous aide à séparer les préoccupations dans notre application. Cela signifie que chaque fichier n'est responsable que d'un seul composant, et vous ne masquerez pas la source du composant si vous souhaitez le réutiliser dans votre application :

import useFetchPosts from &#39;../hooks/useFetchPosts.js&#39;;

export default function FeaturedPosts() {
  const posts = useFetchPosts()

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}
Copier après la connexion
import useFetchPosts from &#39;../hooks/useFetchPosts.js&#39;;

export default function FeaturedPosts() {
  const posts = useFetchPosts()

  return (
    <ul>
      {posts.map((post) => (
        <li onClick={event => {
          console.log(event.target, &#39;clicked!&#39;);
        }} key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}
Copier après la connexion
import useFetchPosts from &#39;../hooks/useFetchPosts.js&#39;;

export default function FeaturedPosts() {
  const posts = useFetchPosts()
  
  function handlePostClick(event) {
    console.log(event.target, &#39;clicked!&#39;);   
  }

  return (
    <ul>
      {posts.map((post) => (
        <li onClick={handlePostClick} key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}
Copier après la connexion

De plus, en incluant chaque composant individuel dans son propre fichier, vous évitez a Le fichier devient trop volumineux.

4. Déplacez la fonction partagée dans un hook React

Dans le composant FeaturedPosts, supposons que vous souhaitiez obtenir des données d'article de l'API au lieu d'utiliser de fausses données. Vous pouvez utiliser l'API fetch pour y parvenir :

export default function App() {
  return (
    <main style={{ textAlign: &#39;center&#39; }}>
      <Navbar title="大标题" />
    </main>
  );
}

function Navbar({ title }) {
  return (
    <div style={{ marginTop: &#39;20px&#39; }}>
      <h1 style={{ fontWeight: &#39;bold&#39; }}>{title}</h1>
    </div>
  )
}
Copier après la connexion

Mais que se passe-t-il si vous souhaitez effectuer cette requête de données sur plusieurs composants ?

Supposons qu'en plus du composant FeaturedPosts, il existe un autre composant nommé Posts qui contient les mêmes données. Nous devons copier la logique pour obtenir les données et la coller dans le composant. Pour éviter la duplication de code, vous pouvez définir un nouveau hook React, que vous pouvez appeler useFetchPosts :
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>
  );
}
Copier après la connexion
De cette façon, vous pouvez le réutiliser dans n'importe quel composant, y compris le composant FeaturedPosts :

export default function EditButton({ post }) {
  const user = useAuthUser();  
  const isPostAuthor = post.author.userId !== user && user.userId;
    
  return isPostAuthor ? <EditButton /> : null;
}
Copier après la connexion
Copier après la connexion

5 Supprimez JS de JSX

. Une autre façon de simplifier vos composants consiste à supprimer autant de JavaScript que possible de JSX. Jetez un œil à l'exemple suivant :

export default function EditButton({ post }) {
  const user = useAuthUser();  
  const isPostAuthor = post.author.userId !== user?.userId;
    
  return isPostAuthor ? <EditButton /> : null;
}
Copier après la connexion
Copier après la connexion

Ici, nous essayons de gérer l'événement click de l'article, et vous pouvez voir que notre JSX devient plus difficile à lire. Étant donné que la fonction est incluse en tant que fonction en ligne, cela obscurcit l'objectif de ce composant et ses fonctions associées. Comment résoudre ce problème ? Vous pouvez extraire la fonction en ligne contenant onClick dans une fonction de gestionnaire distincte et lui donner le nom handlePostClick. Cela rend JSX plus lisible :

export default function App() {
  return (
    <Layout>
      <Routes />
    </Layout>
  );
}
Copier après la connexion
Copier après la connexion

6. Formater les styles en ligne

🎜Écrire trop de styles en ligne dans JSX rendra le code plus difficile à lire et deviendra volumineux :🎜
const App = () => (
  <Layout>
    <Routes />
  </Layout>
);

export default App;
Copier après la connexion
Copier après la connexion
🎜 Nous souhaitons déplacer les styles en ligne dans des feuilles de style CSS à chaque fois. possible. Ou organisez-les en objets : 🎜
function PostList() {
  const posts = usePostData();  
    
  return posts.map(post => (
    <PostListItem key={post.id} post={post} />  
  ))
}
Copier après la connexion
Copier après la connexion
🎜 Généralement, il est préférable d'écrire ces styles dans une feuille de style CSS. Si le style doit être généré dynamiquement, il peut être défini dans un objet. 🎜🎜🎜7. Utilisation de l'opérateur de chaînage facultatif🎜🎜🎜En JavaScript, nous devons d'abord nous assurer qu'un objet existe avant de pouvoir accéder à ses propriétés. Si la valeur de l'objet est indéfinie ou nulle, une erreur de type en résultera. 🎜🎜Regardez ci-dessous un exemple dans lequel les utilisateurs peuvent modifier leurs publications publiées. Le composant EditButton ne sera affiché que si isPostAuthor est vrai, c'est-à-dire si l'identifiant de l'utilisateur authentifié est le même que l'identifiant de l'auteur de la publication. 🎜
export default function EditButton({ post }) {
  const user = useAuthUser();  
  const isPostAuthor = post.author.userId !== user && user.userId;
    
  return isPostAuthor ? <EditButton /> : null;
}
Copier après la connexion
Copier après la connexion

这段代码的问题是 user 可能是 undefined. 这就是为什么我们必须在尝试获取 userId 属性之前使用 && 运算符来确保 user 是一个对象。如果我要访问一个对象中的另一个对象,就不得不再包含一个 && 条件。 这会导致代码变得复杂、难以理解。

JavaScript 可选链运算符(?.)允许我们在访问属性之前检查对象是否存在。用它来简化上面的代码:

export default function EditButton({ post }) {
  const user = useAuthUser();  
  const isPostAuthor = post.author.userId !== user?.userId;
    
  return isPostAuthor ? <EditButton /> : null;
}
Copier après la connexion
Copier après la connexion

这样将防止任何类型错误,并允许我们编写更清晰的条件逻辑。

8. 带括号的隐式返回

在 React 应用中可以使用 function 关键字的函数声明语法编写组件,也可以使用设置为变量的箭头函数。使用 function 关键字的组件必须在返回任何 JSX 之前使用 return 关键字。

export default function App() {
  return (
    <Layout>
      <Routes />
    </Layout>
  );
}
Copier après la connexion
Copier après la connexion

通过将返回的代码包裹在一组括号中,可以通过隐式返回(不使用 return 关键字)从函数返回多行 JavaScript 代码。

对于使用箭头函数的组件,不需要包含 return 关键字,可以只返回带有一组括号的 JSX。

const App = () => (
  <Layout>
    <Routes />
  </Layout>
);

export default App;
Copier après la connexion
Copier après la connexion

此外,当使用 .map() 迭代元素列表时,还可以跳过 return 关键字并仅在内部函数的主体中使用一组括号返回 JSX。

function PostList() {
  const posts = usePostData();  
    
  return posts.map(post => (
    <PostListItem key={post.id} post={post} />  
  ))
}
Copier après la connexion
Copier après la connexion

9. 使用空值合并运算符

在 JavaScript 中,如果某个值是假值(如 null、undefined、0、''、NaN),可以使用 || 条件来提供一个备用值。

例如,在产品页面组件需要显示给定产品的价格,可以使用 || 来有条件地显示价格或显示文本“产品不可用”。

export default function ProductPage({ product }) {    
  return (
     <>
       <ProductDetails />
       <span>
          {product.price || "产品不可用"}
       </span>
     </>
  );
}
Copier après la connexion

现有的代码存在一个问题,如果商品的价格为0,也不会显示产品的价格而显示"产品不可用"。如果左侧为null或者undefined,而不是其他假值,就需要一个更精确的运算符来仅返回表达式的右侧。

这时就可以使用空值合并运算符,当左侧操作数为null或者 undefined 时,将返回右侧操作数。 否则它将返回其左侧操作数:

null ?? &#39;callback&#39;;
// "callback"

0 ?? 42;
// 0
Copier après la connexion

可以使用空值合并运算符来修复上面代码中的问题:

export default function ProductPage({ product }) {    
  return (
     <>
       <ProductDetails />
       <span>{product.price ?? "产品不可用"}
     </>
  );
}
Copier après la connexion

10. 使用三元表达式

在 React 组件中编写条件时,三元表达式是必不可少的,经常用于显示或隐藏组件和元素。

当然,我们用可以使用三元表达式和模板字符串来给 React 元素动态添加或删除类名。

export default function App() {
  const { isDarkMode } = useDarkMode();
    
  return (
    <main className={`body ${isDarkMode ? "body-dark" : "body-light"}`}>
      <Routes />
    </main>
  );
}
Copier après la connexion

这种条件逻辑也可以应用于任何 props:

export default function App() {
  const { isMobile } = useDeviceDetect();
    
  return (
    <Layout height={isMobile ? &#39;100vh&#39; : &#39;80vh&#39;}>
      <Routes />
    </Layout>
  );
}
Copier après la connexion

【推荐学习:javascript视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:juejin.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal