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
道具来设置最初活动的手风琴项目。
接下来,让我们创建AccordionItem
和AccordionContent
组件:
// 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
组件跟踪鼠标位置并将其传递给children
prop,这是一个函数。
#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
组件接受 propsvalue
和defaultValue
props。如果value
定义了 prop,它就是一个受控组件,父组件管理它的状态。如果defaultValue
定义了 prop,则它是不受控制的组件,Input
组件管理自己的状态。
#4. 高阶组件
高阶组件 (HOC) 是接受组件并返回具有附加功能的新组件的函数。这种模式可以帮助您在不修改原始组件的情况下创建可重用和可组合的组件。(React.memo
是 HOC 的一个例子。)
考虑一个简单的withLoading
HOC:
// 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
组件接受一个children
prop,它是一个接收参数的回调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