5 个强大的模式,让 React 代码更干净、更易维护

本文介绍了五个强大的React代码模式,包括复合组件、RenderProps、受控与非受控组件、高阶组件和RenderPropCallbacks,结合TypeScript,以实现更清晰、更易维护的代码结构,提高代码的灵活性和可重用性。
摘要由CSDN通过智能技术生成

5 个强大的模式,让 React 代码更干净、更易维护

利用这些强大的模式将您的 React 代码提升到一个新的水平,无论您是初学者还是中级 React 开发人员。

简介:5 个强大的 React 代码模式

编写干净且可维护的代码对于任何应用程序的长期成功都是必不可少的。随着 React 项目的增长,采用高级设计模式可以帮助您管理复杂性并提高可维护性。

在本文中,我们将探索五种高级 React 模式,它们可以使用 TypeScript 使您的代码更清晰、更易于维护。

#1. 复合组件

复合组件通过管理共享状态并允许您以各种方式组合它们来帮助创建灵活且可重用的组件。

考虑一个简单的Accordion组件:

// Accordion.tsx
import React, { createContext, useState, useContext } from 'react'

interface AccordionProps {
  defaultIndex?: number
}

const AccordionContext = createContext<{
  activeIndex: number
  setActiveIndex: (index: number) => void
}>({
  activeIndex: 0,
  setActiveIndex: () => {},
})

const Accordion: React.FC<AccordionProps> = ({ defaultIndex = 0, children }) => {
  const [activeIndex, setActiveIndex] = useState(defaultIndex)

  return (
    <AccordionContext.Provider value={{ activeIndex, setActiveIndex }}>
      {children}
    </AccordionContext.Provider>
  )
}

export default Accordion

在这里,我们使用上下文来管理复合组件之间的共享状态。该Accordion组件接受一个defaultIndex道具来设置最初活动的手风琴项目。

接下来,让我们创建AccordionItemAccordionContent组件:

// AccordionItem.tsx
import React, { useContext } from 'react'
import { AccordionContext } from './Accordion'

interface AccordionItemProps {
  index: number
}

const AccordionItem: React.FC<AccordionItemProps> = ({ index, children }) => {
  const { activeIndex, setActiveIndex } = useContext(AccordionContext)

  const handleClick = () => {
    setActiveIndex(index)
  }

  return (
    <div>
      <button onClick={handleClick}>{`Item ${index + 1}`}</button>
      {activeIndex === index && children}
    </div>
  )
}

export default AccordionItem

AccordionItem组件使用AccordionContext来访问和更新共享状态。单击时,它会设置活动索引并显示其子项(如果它是活动项)。

#2. Render Props

Render props(或简称为“props”)是一种使用值为函数的prop在组件之间共享代码的技术。此模式可以帮助您创建可重用且灵活的组件,而无需依赖高阶组件或混入。您可能知道props,但让我们回顾一下。

考虑一个简单的MouseTracker组件:

// MouseTracker.tsx
import React, { useState } from 'react'

interface MouseTrackerProps {
  children: (position: { x: number; y: number }) => React.ReactNode
}

const MouseTracker: React.FC<MouseTrackerProps> = ({ children }) => {
  const [position, setPosition] = useState({ x: 0, y: 0 })

  const handleMouseMove = (event: React.MouseEvent) => {
    setPosition({ x: event.clientX, y: event.clientY })
  }

  return (
    <div onMouseMove={handleMouseMove} style={{ height: '100vh' }}>
      {children(position)}
    </div>
  )
}

export default MouseTracker

在此示例中,MouseTracker组件跟踪鼠标位置并将其传递给childrenprop,这是一个函数。

#3. 受控和非受控组件

受控组件允许父组件管理它们的状态,而非受控组件管理它们自己的状态。通过一起使用受控和非受控组件,您可以创建更灵活和可维护的表单。(或者只使用React Hook Form!😹)

考虑一个简单的Input组件:

// Input.tsx
import React from 'react'

interface InputProps {
  value?: string
  defaultValue?: string
  onChange?: (value: string) => void
}

const Input: React.FC<InputProps> = ({ value, defaultValue, onChange }) => {
  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    onChange?.(event.target.value)
  }

  return <input value={value} defaultValue={defaultValue} onChange={handleChange} />
}

export default Input

在此示例中,Input组件接受 propsvaluedefaultValueprops。如果value定义了 prop,它就是一个受控组件,父组件管理它的状态。如果defaultValue定义了 prop,则它是不受控制的组件,Input组件管理自己的状态。

#4. 高阶组件

高阶组件 (HOC) 是接受组件并返回具有附加功能的新组件的函数。这种模式可以帮助您在不修改原始组件的情况下创建可重用和可组合的组件。(React.memo是 HOC 的一个例子。)

考虑一个简单的withLoadingHOC:

// withLoading.tsx
import React, { ComponentType } from 'react'

interface WithLoadingProps {
  isLoading: boolean
}

const withLoading = <P extends object>(
  WrappedComponent: ComponentType<P>
): React.FC<P & WithLoadingProps> => ({ isLoading, ...props }: WithLoadingProps) =>
  isLoading ? <div>Loading...</div> : <WrappedComponent {...(props as P)} />

export default withLoading

这个HOC接收一个并返回一个新的组件,该组件isLoading在为true时显示一个加载指示器。

#5.Render Prop Callbacks

Render prop callbacks 是一种使用回调函数作为 prop 在组件之间共享代码的技术。此模式可以帮助您创建更具可组合性和可重用性的组件。

“回调函数是作为参数传递给另一个函数的函数,然后在外部函数内部调用该函数以完成某种操作。” — MDN 文档

考虑一个简单的Toggle组件:

// Toggle.tsx
import React, { useState } from 'react'

interface ToggleProps {
  children: (on: boolean, toggle: () => void) => React.ReactNode
}

const Toggle: React.FC<ToggleProps> = ({ children }) => {
  const [on, setOn] = useState(false)

  const toggle = () => {
    setOn((prevState) => !prevState)
  }

  return <>{children(on, toggle)}</>
}

export default Toggle

在这个例子中,Toggle组件接受一个childrenprop,它是一个接收参数的回调on函数toggle。参数on表示切换的当前状态,而toggle是切换状态的函数。

结论:5 个强大的 React 代码模式

在本文中,我们探索了 5 种强大的模式,同时使用 TypeScript 创建更清晰、更易读且更易于维护的 React 代码。

通过使用这些模式,您可以管理复杂性并提高可重用性,从而更轻松地维护和更新代码库。

当您继续使用 React 时,请牢记这些模式并在适当的地方应用它们以创建更好的代码。

翻译自:5 Powerful Patterns for Cleaner and More Maintainable React Code by Dr. Derek Austin
链接:https://medium.com/react-in-the-real-world/5-powerful-patterns-for-cleaner-and-more-maintainable-react-code-d71c37701109

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值