首页 > 其他分享 >日常工作中需要避免的9个React坏习惯

日常工作中需要避免的9个React坏习惯

时间:2024-07-19 17:42:22浏览次数:6  
标签:function return 示例 items 坏习惯 React 日常 组件

日常工作中需要避免的9个React坏习惯

前言

React是前端开发领域中最受欢迎的JavaScript库之一,但有时候在编写React应用程序时,可能陷入一些不佳的习惯和错误做法。这些不佳的习惯可能导致性能下降、代码难以维护,以及其他问题。在本文中,我们将探讨日常工作中应该避免的9个坏React习惯,并提供相关示例代码来说明这些问题以及如何避免它们。

1. 属性传递问题(Prop Drilling)

属性传递问题是一种常见的不良习惯,它发生在将属性从一个组件传递到多层嵌套的子组件时。这可能导致性能问题和代码可读性降低。理想情况下,应该尽量避免将属性传递超过2层。下面是一个示例:

  // 父组件
  function ParentComponent() {
  const data = 'Some data';
   
  return (
  <ChildComponent data={data} />
  );
  }
   
  // 子组件
  function ChildComponent({ data }) {
  return (
  <GrandchildComponent data={data} />
  );
  }
   
  // 孙子组件
  function GrandchildComponent({ data }) {
  // 使用数据
  return <div>{data}</div>;
  }

在上面的示例中,data属性通过多个嵌套层级传递,这可能导致性能问题和可读性问题。解决这个问题的方法之一是使用React的上下文(context)来共享数据,或者重新组织组件结构。

2. 导入过多所需的内容

React应用程序中,导入过多的依赖项可能会导致包变得庞大,从而增加加载时间。在日常工作中,确保只导入需要的依赖项。例如,避免导入整个库,而只导入所需的功能。

  // 不良示例 - 导入整个库
  import _ from 'lodash';
   
  // 良好示例 - 只导入所需的功能
  import { someFunction } from 'lodash';

这有助于减小包的大小,提高应用程序性能。

3. 不将业务逻辑与组件逻辑分离

React中,尽量将业务逻辑与UI组件逻辑分开,以提高代码的可读性和可维护性。将业务逻辑提取到独立的服务文件或模块中,以使组件保持简单。以下是一个示例:

  // 不良示例 - 业务逻辑混杂在组件中
  function UserProfile() {
  const user = getUserData(); // 从API获取用户数据
   
  return (
  <div>
  <h1>{user.name}</h1>
  <p>{user.email}</p>
  </div>
  );
  }
   
  // 良好示例 - 业务逻辑分离
  function UserProfile() {
  const user = useUserData(); // 从独立服务获取用户数据
   
  return (
  <div>
  <h1>{user.name}</h1>
  <p>{user.email}</p>
  </div>
  );
  }

通过将业务逻辑提取到独立的useUserData函数中,使组件更加清晰和可维护。

4. 在每次渲染时重复执行工作

React组件可能会在不同时间点重新渲染,如果不小心,某些工作可能会在每次渲染时都重复执行,这会降低性能。为了避免这种情况,可以使用useMemouseCallback来记忆化操作,以便它们不会在每次渲染时重新计算。以下是一个示例:

  function List({ items }) {
  // 不使用useMemo - 每次渲染都会重新过滤
  const filteredItems = items.filter(item => item.active);
   
  // 使用useMemo - 只在items发生变化时重新过滤
  const filteredItems = useMemo(() => items.filter(item => item.active), [items]);
  }

通过使用useMemo,可以避免在每次渲染时重新计算filteredItems,从而提高性能。

5. 不正确使用useEffect钩子

useEffect钩子用于处理副作用,但如果不正确使用它,可能会导致创建多个事件监听器,这会引发问题。正确使用useEffect的方法包括将清理函数返回以取消订阅,以及使用空的依赖数组以确保只运行一次。以下是一个示例:

  // 不良示例 - 每次渲染都会创建新的事件监听器
  useEffect(() => {
  window.addEventListener('resize', handleResize);
  return () => {
  window.removeEventListener('resize', handleResize);
  };
  });
   
  // 良好示例 - 只在组件挂载时创建事件监听器
  useEffect(() => {
  window.addEventListener('resize', handleResize);
  return () => {
  window.removeEventListener('resize', handleResize);
  };
  }, []); // 空的依赖数组

通过使用空的依赖数组,确保了事件监听器只在组件挂载时创建一次。

6. 不正确使用布尔运算符

React组件中,经常需要根据条件来渲染不同的内容。然而,不正确使用布尔运算符可能会导致意外的问题。例如:

  // 不良示例 - 使用 && 运算符
  function ShoppingCart({ items }) {
  return (
  <div>
  {items.length && <p>Items in cart: {items.length}</p>}
  </div>
  );
  }

在上述示例中,当items.length0时,<p>元素将不会渲染,这可能不是我们期望的结果。为了避免这种情况,最好将条件转化为布尔值,如下所示:

  // 良好示例 - 使用Boolean()将条件转换为布尔值
  function ShoppingCart({ items }) {
  return (
  <div>
  {Boolean(items.length) && <p>Items in cart: {items.length}</p>}
  </div>
  );
  }

通过将条件转换为布尔值,我们可以确保<p>元素按预期渲染。

7. 到处使用三元表达式进行条件渲染

三元表达式是一种强大的条件渲染工具,但滥用它可能会导致代码难以阅读。特别是当多个三元表达式嵌套在一起时,代码会变得混乱。考虑以下示例:

  // 不良示例 - 多个嵌套的三元表达式
  function UserProfile({ user, isAdmin, isOwner }) {
  return (
  <div>
  {isAdmin ? (
  <p>Admin</p>
  ) : isOwner ? (
  <p>Owner</p>
  ) : (
  <p>User</p>
  )}
  </div>
  );
  }

在上述示例中,多个三元表达式嵌套在一起,使代码难以理解。为了提高可读性,可以考虑使用函数或组件来代替三元表达式。以下是一个改进的示例:

  // 良好示例 - 使用函数代替三元表达式
  function UserProfile({ user, isAdmin, isOwner }) {
  function getUserRole() {
  if (isAdmin) {
  return 'Admin';
  } else if (isOwner) {
  return 'Owner';
  } else {
  return 'User';
  }
  }
   
  return (
  <div>
  <p>{getUserRole()}</p>
  </div>
  );
  }

通过使用函数,我们使代码更易读和维护。

8. 不定义属性类型或不解构属性

为组件的属性定义类型和解构属性是一种良好的实践,它有助于提高代码的可维护性和稳定性。在日常工作中,我们应该使用PropTypesTypeScript等工具来为属性添加类型定义,并解构属性以使其更清晰。以下是一个示例:

  // 不良示例 - 未定义属性类型和未解构属性
  function Person(props) {
  return (
  <div>
  <p>Name: {props.name}</p>
  <p>Age: {props.age}</p>
  </div>
  );
  }
   
  // 良好示例 - 定义属性类型和解构属性
  import PropTypes from 'prop-types';
   
  function Person({ name, age }) {
  return (
  <div>
  <p>Name: {name}</p>
  <p>Age: {age}</p>
  </div>
  );
  }
   
  Person.propTypes = {
  name: PropTypes.string,
  age: PropTypes.number,
  };

通过定义属性类型和解构属性,可以提高代码的可读性,并在属性类型错误时获得警告。

9. 较大的应用程序没进行代码拆分

对于大型React应用程序,应该考虑使用代码拆分(Code Splitting)以提高初始加载性能。代码拆分允许将代码分割为较小的块,这些块可以在需要时加载,从而减小初始包的大小。以下是一个示例:

  import Loadable from 'react-loadable';
   
  const AsyncComponent = Loadable({
  loader: () => import('./AsyncComponent'),
  loading: () => <div>Loading...</div>,
  });
   
  function App() {
  return (
  <div>
  <AsyncComponent />
  </div>
  );
  }

通过使用代码拆分,可以提高应用程序的加载速度,特别是对于较大的应用程序。

结论

React开发中,避免这九个不良习惯可以提高代码质量、性能和可维护性。通过使用示例代码来说明这些问题以及如何避免它们,可以帮助我们在日常工作中编写更高质量的React应用程序。

标签:function,return,示例,items,坏习惯,React,日常,组件
From: https://www.cnblogs.com/sexintercourse/p/18312010

相关文章

  • [email protected](62)[email protected](11)- 中间件2 - redux-thunk
    目录1,介绍举例2,原理和实现实现3,注意点1,介绍一般情况下,action是一个平面对象,并会通过纯函数来创建。exportconstcreateAddUserAction=(user)=>({type:ADD_USER,payload:user,});这样是有一些限制的无法使用异步的,比如在请求接口之后再做一......
  • Error: Expected ref to be a function, a string, an object returned by React.crea
    1、完整报错:Error:Expectedreftobeafunction,astring,anobjectreturnedbyReact.createRef(),ornull.atcoerceRef(react-dom.development.js:14873:1)atreconcileSingleElement(react-dom.development.js:15723:1)atreconcileChildFibers(re......
  • 深度解析:在 React 中实现类似 Vue 的 KeepAlive 组件
    深度解析:在React中实现类似Vue的KeepAlive组件在前端开发中,Vue的keep-alive组件是一个非常强大的工具,它可以在组件切换时缓存组件的状态,避免重新渲染,从而提升性能。那么,如何在React中实现类似的功能呢?本文将带你深入探讨,并通过代码示例一步步实现这个功能。什么是Ke......
  • 深入探讨 Vue 3 中的 `ref` 和 `reactive`:你需要知道的一切
    深入探讨Vue3中的ref和reactive:你需要知道的一切在Vue3中,响应式系统是其核心特性之一。它使得数据和视图能够自动同步更新,从而简化了开发过程。在这个系统中,ref和reactive是两个非常重要的API。虽然它们都用于创建响应式数据,但它们的使用场景和工作原理却有所不同。......
  • 深度解析:React 与 Vue.js 的相似性与差异性
    深度解析:React与Vue.js的相似性与差异性在现代前端开发中,React和Vue.js是两大热门的JavaScript框架。它们都旨在简化用户界面的开发,但在实现方式和设计理念上存在显著差异。本文将深入探讨React和Vue.js的相似性与差异性,并通过代码示例来帮助你更好地理解它们。相似......
  • 解决React Warning: Can't perform a React state update on an unmounted component.
    在写react程序时遇到警告:Warning:Can'tperformaReactstateupdateonanunmountedcomponent.Thisisano-op,butitindicatesamemoryleakinyourapplication.Tofix,cancelallsubscriptionsandasynchronoustasksinauseEffectcleanupfunction.我们......
  • yearrecord——一个类似痕迹墙的React数据展示组件
    介绍一下自己做的一个类似于力扣个人主页提交记录和GitHub主页贡献记录的React组件。下图分别是力扣个人主页提交记录和GitHub个人主页的贡献记录,像这样类似痕迹墙的形式可以比较直观且高效得展示一段时间内得数据记录。然而要从0实现这个功能还是有一些麻烦得,并且该功能可用......
  • Java中的响应式编程与Reactor框架使用详解
    Java中的响应式编程与Reactor框架使用详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!一、引言响应式编程是一种面向数据流和变化传播的编程范式,它适用于处理异步数据流和事件驱动的场景。Reactor框架是在Java中实现响应式编程的强大工具,本文将深入......
  • 创建react项目
    1.创建项目npxcreate-react-appname//1.npxnode的工具命令//2.create-react-app创建react项目的固定写法//3.name项目名称2.目录结构              重点关注src目录,入口文件为src/index.js,也就是运行的起点,导入项目的根组件并......
  • 我日常是如何使用LLM工具的:你的LLM工具没用起来,可能是因为方法不对。
    引言我对Prompt认知经历了2个阶段:第一阶段:去年3月-11月,我认为Prompt最终会灭亡。第二阶段:去年12月至今,我有两个理解:在主流LLM工具(比如ChatGPT,文心一言等大模型厂商的对话产品,以下统称LLM工具)中,Prompt能力未来会像我们现在使用word,ppt,excel的能力......