”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 每个开发人员都应该了解可扩展和高效应用程序的顶级 React 设计模式

每个开发人员都应该了解可扩展和高效应用程序的顶级 React 设计模式

发布于2024-11-06
浏览:451

Top React Design Patterns Every Developer Should Know for Scalable and Efficient Apps

随着 React 继续主导前端生态系统,掌握其设计模式可以显着提高应用程序的效率和可扩展性。 React 设计模式提供了组织和构建组件、管理状态、处理 props 和提高可重用性的最佳实践。在本博客中,我们将探讨一些关键的 React 设计模式,这些模式可以使您的开发过程从优秀走向卓越。

1. 展示组件和容器组件

React 中的基本模式之一是 演示组件和容器组件 模式,这都是关于分离关注点的:

  • 演示组件: 这些组件负责事物的外观。他们通过 props 接收数据和回调,但没有自己的逻辑。它们的唯一目的是渲染 UI。

  • 容器组件: 这些组件管理事物的工作方式。它们包含逻辑、管理状态并处理数据获取或事件处理。容器组件将数据传递给展示组件。


// Presentational Component
const UserProfile = ({ user }) => (
  

{user.name}

{user.email}

); // Container Component const UserProfileContainer = () => { const [user, setUser] = useState({ name: 'John Doe', email: '[email protected]' }); return ; };

这种模式鼓励关注点分离,使代码更易于维护和测试。

2. 高阶组件(HOC)

高阶组件 (HOC) 是重用组件逻辑的强大设计模式。 HOC 是一个函数,它接受一个组件并返回一个具有增强行为或添加功能的新组件。

此模式通常用于横切关注点,例如身份验证、主题或数据获取。


// Higher-Order Component for authentication
const withAuth = (WrappedComponent) => {
  return (props) => {
    const isAuthenticated = // logic to check auth;

    if (!isAuthenticated) {
      return 
You need to log in!
; } return ; }; }; // Usage const Dashboard = () =>
Welcome to the dashboard
; export default withAuth(Dashboard);

HOC 通过跨多个组件实现可重用逻辑来促进 DRY(不要重复自己)原则。

3. 渲染道具

Render Props 模式涉及将函数作为 prop 传递给组件,从而允许基于该函数动态渲染内容。这对于在不使用 HOC 的情况下在组件之间共享状态逻辑特别有用。


// Render Prop Component
class MouseTracker extends React.Component {
  state = { x: 0, y: 0 };

  handleMouseMove = (event) => {
    this.setState({ x: event.clientX, y: event.clientY });
  };

  render() {
    return (
      
{this.props.render(this.state)}
); } } // Usage const App = () => (

Mouse position: {x}, {y}

} /> );

此模式通过将逻辑与 UI 分离来为您提供灵活性,使组件更加可重用和可定制。

4. 复合组件

复合组件模式通常用于react-select 或react-table 等库中。它允许父组件控制一组子组件。这种模式提高了构建可重用和动态界面的灵活性。


// Compound Component
const Tabs = ({ children }) => {
  const [activeTab, setActiveTab] = useState(0);

  return (
    
{children.map((child, index) => ( ))}
{children[activeTab]}
); }; // Usage
Content of Tab 1
Content of Tab 2
;

此模式为父子通信提供了一个干净的 API,同时保持组件的灵活性和可定制性。

5. 受控组件与非受控组件

React 提供了两种管理表单输入的方式:受控组件非受控组件

  • 受控组件:这些组件的状态完全由 React 通过 props 控制,这使得它们更加可预测。

  • 不受控制的组件:这些组件依赖于 ref 来直接操作 DOM,提供较少的控制,但可能提高性能。


// Controlled Component
const ControlledInput = () => {
  const [value, setValue] = useState('');

  return  setValue(e.target.value)} />;
};

// Uncontrolled Component
const UncontrolledInput = () => {
  const inputRef = useRef();

  const handleClick = () => {
    console.log(inputRef.current.value);
  };

  return ;
};


在这些模式之间进行选择取决于您是否需要细粒度控制或轻量级性能优化。

6. 自定义挂钩

React Hooks 允许我们以可重用的方式构建自定义逻辑。通过将通用逻辑提取到自定义钩子中,我们可以避免代码重复并使我们的代码库更加模块化。


// Custom Hook
const useFetch = (url) => {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch(url)
      .then((response) => response.json())
      .then((data) => setData(data))
      .catch((error) => setError(error));
  }, [url]);

  return { data, error };
};

// Usage
const DataFetchingComponent = () => {
  const { data, error } = useFetch('https://api.example.com/data');

  if (error) return 

Error: {error.message}

; if (!data) return

Loading...

; return
{data.someField}
; };

自定义挂钩可以更好地分离关注点并以声明性方式重用公共功能。

结论

设计模式是编写干净、可维护和可扩展的 React 应用程序的关键部分。通过利用展示组件和容器组件、HOC、渲染道具、复合组件和自定义挂钩等模式,您可以确保您的代码灵活、可重用且易于理解。

理解和实现这些模式可以极大地改善您的开发工作流程,使您的 React 项目更加有组织和高效。尝试将它们合并到您的下一个项目中,体验代码质量和可维护性方面的差异!

版本声明 本文转载于:https://dev.to/ishanbagchi/top-react-design-patterns-every-developer-should-know-for-scalable-and-efficient-apps-245e?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 在 Hacktoberfest 中做出贡献的新方式:直接在前端 AI
    在 Hacktoberfest 中做出贡献的新方式:直接在前端 AI
    Hacktoberfest 又回来了,今年为开发者带来了一种令人兴奋的新参与方式。 您现在可以直接通过 Webcrumbs 平台上的 Frontend AI 创建和提交模板,而不是传统的 GitHub Pull 请求。只需前往tools.webcrumbs.org,对模板进行编码,然后在准备好后点击...
    编程 发布于2024-11-07
  • 为什么使用不带括号的函数指针时“cout”打印“1”?
    为什么使用不带括号的函数指针时“cout”打印“1”?
    为什么“cout a function without call it (not f() but f;). Print 1 Always?”在此代码中,该代码尝试在不使用括号的情况下“调用”名为 pr 的函数。然而,这实际上并不是调用该函数。相反,它将函数指针传递给 cout 函数。当函数指针隐式转...
    编程 发布于2024-11-07
  • 让您的网页更快
    让您的网页更快
    什么是 DOM?它吃什么? DOM(文档对象模型)是网页及其开发的基础。它是 HTML 和 XML 文档的编程接口,以树状对象表示文档的结构。有树枝和树叶。文档中的每个元素、属性和文本片段都成为该树中的一个节点。它允许 JavaScript 与 HTML 元素交互、修改它们或添加新...
    编程 发布于2024-11-07
  • JavaScript 中的 require 与 import
    JavaScript 中的 require 与 import
    我记得当我开始编码时,我会看到一些js文件使用require()来导入模块和其他文件使用import。这总是让我感到困惑,因为我并不真正理解其中的区别是什么,或者为什么项目之间存在不一致。如果您想知道同样的事情,请继续阅读! 什么是 CommonJS? CommonJS 是一组用于在...
    编程 发布于2024-11-07
  • 使用镜像部署 Vite/React 应用程序:完整指南
    使用镜像部署 Vite/React 应用程序:完整指南
    在 GitHub Pages 上部署 Vite/React 应用程序是一个令人兴奋的里程碑,但这个过程有时会带来意想不到的挑战,特别是在处理图像和资产时。这篇博文将引导您完成整个过程,从最初的部署到解决常见问题并找到有效的解决方案。 无论您是初学者还是有经验的人,本指南都将帮助您避免常见的陷阱,并...
    编程 发布于2024-11-07
  • 我如何在我的 React 应用程序中优化 API 调用
    我如何在我的 React 应用程序中优化 API 调用
    作为 React 开发者,我们经常面临需要通过 API 同步多个快速状态变化的场景。对每一个微小的变化进行 API 调用可能效率低下,并且会给客户端和服务器带来负担。这就是去抖和巧妙的状态管理发挥作用的地方。在本文中,我们将构建一个自定义 React 钩子,通过合并有效负载和去抖 API 调用来捕获...
    编程 发布于2024-11-07
  • 我们走吧!
    我们走吧!
    为什么你需要尝试 GO Go 是一种快速、轻量级、静态类型的编译语言,非常适合构建高效、可靠的应用程序。它的简单性和简洁的语法使其易于学习和使用,特别是对于新手来说。 Go 的突出功能包括内置的 goroutine 并发性、强大的标准库以及用于代码格式化、测试和依赖管理的强大工具。...
    编程 发布于2024-11-06
  • 如何将 PNG 图像编码为 CSS 数据 URI 的 Base64?
    如何将 PNG 图像编码为 CSS 数据 URI 的 Base64?
    在 CSS 数据 URI 中对 PNG 图像使用 Base64 编码为了使用数据 URI 将 PNG 图像嵌入到 CSS 样式表中,PNG 数据必须首先编码为 Base64 格式。此技术允许将外部图像文件直接包含在样式表中。Unix 命令行解决方案:base64 -i /path/to/image....
    编程 发布于2024-11-06
  • API 每小时数据的响应式 JavaScript 轮播
    API 每小时数据的响应式 JavaScript 轮播
    I almost mistook an incomplete solution for a finished one and moved on to work on other parts of my weather app! While working on the carousel that w...
    编程 发布于2024-11-06
  • 用于 Web 开发的 PHP 和 JavaScript 之间的主要区别是什么?
    用于 Web 开发的 PHP 和 JavaScript 之间的主要区别是什么?
    PHP 与 JavaScript:服务器端与客户端 PHP 的作用与 JavaScript 不同。 PHP 运行在服务器端。服务器运行应用程序。除其他外,它还处理表单。当您提交表单时,PHP 会对其进行处理。另一方面,JavaScript 是客户端的。它在浏览器中运行。它处理页面交...
    编程 发布于2024-11-06
  • 如何在 C++ 中迭代结构和类成员以在运行时访问它们的名称和值?
    如何在 C++ 中迭代结构和类成员以在运行时访问它们的名称和值?
    迭代结构体和类成员在 C 中,可以迭代结构体或类的成员来检索它们的名称和价值观。以下是实现此目的的几种方法:使用宏REFLECTABLE 宏可用于定义允许自省的结构。该宏将结构体的成员定义为以逗号分隔的类型名称对列表。例如:struct A { REFLECTABLE ( ...
    编程 发布于2024-11-06
  • 如果需要准确答案,请避免浮动和双精度
    如果需要准确答案,请避免浮动和双精度
    float 和 double 问题: 专为科学和数学计算而设计,执行二进制浮点运算。 不适合货币计算或需要精确答案的情况。 无法准确表示10的负次方,例如0.1,从而导致错误。 示例1: 减去美元金额时计算错误: System.out.println(1.03 - 0.42); // Result...
    编程 发布于2024-11-06
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    编程 发布于2024-11-06
  • 如何在 Python 中使用代理运行 Selenium Webdriver?
    如何在 Python 中使用代理运行 Selenium Webdriver?
    使用 Python 中的代理运行 Selenium Webdriver当您尝试将 Selenium Webdriver 脚本导出为 Python 脚本并从命令行执行时,可能会遇到在使用代理的情况下出现错误。本文旨在解决此问题,提供一种使用代理有效运行脚本的解决方案。代理集成要使用代理运行 Selen...
    编程 发布于2024-11-06
  • || 什么时候运算符充当 JavaScript 中的默认运算符?
    || 什么时候运算符充当 JavaScript 中的默认运算符?
    理解 || 的目的JavaScript 中非布尔操作数的运算符在 JavaScript 中,||运算符通常称为逻辑 OR 运算符,通常用于计算布尔表达式。但是,您可能会遇到 || 的情况。运算符与非布尔值一起使用。在这种情况下,||运算符的行为类似于“默认”运算符。它不返回布尔值,而是根据某些规则返...
    编程 发布于2024-11-06

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3