2026-04-09 12:25:56
React高级模式是提升组件复用性与可维护性的设计实践,包括Render Props、高阶组件(HOC)、复合组件和自定义Hook四种核心模式,实际开发中应优先选择自定义Hook和Render Props,遵循组合优于继承的原则。 以下为具体说明:
Render Props模式通过函数类型的render prop传递状态或逻辑,实现逻辑与UI的解耦。例如,封装鼠标追踪组件时,将位置数据通过render函数传递给外部UI组件:
const MouseTracker = ({ render }) => { const [position, setPosition] = useState({ x: 0, y: 0 }); useEffect(() => { const handleMove = (e) => setPosition({ x: e.clientX, y: e.clientY }); window.addEventListener('mousemove', handleMove); return () => window.removeEventListener('mousemove', handleMove); }, []); return <div>{render(position)}</div>;};// 使用<MouseTracker render={({ x, y }) => <p>鼠标位置:{x}, {y}</p>} />优势:逻辑复用性强,适合封装通用行为;局限:可能增加组件层级。
高阶组件(HOC)通过函数接收组件并返回新组件,用于复用横切关注点(如权限控制、日志)。例如,为组件添加加载状态:
const withLoading = (WrappedComponent) => { return (props) => props.isLoading ? <div>加载中...</div> : <WrappedComponent {...props} />;};// 使用const UserListWithLoading = withLoading(UserList);优势:逻辑复用高效;局限:易导致嵌套过深或props冲突,需注意命名空间和属性透传。
复合组件模式通过共享内部状态实现子组件协作,提供清晰的API结构。例如,实现下拉菜单时,父组件管理状态并通过React.cloneElement透传给子组件:
const Dropdown = ({ children }) => { const [isOpen, setIsOpen] = useState(false); return ( <div className="dropdown"> {React.Children.map(children, child => React.isValidElement(child) ? React.cloneElement(child, { isOpen, toggle: () => setIsOpen(!isOpen) }) : child )} </div> );};Dropdown.Button = ({ toggle, isOpen }) => <button onClick={toggle}>{isOpen ? '收起' : '展开'}</button>;Dropdown.Menu = ({ isOpen, children }) => isOpen ? <ul>{children}</ul> : null;// 使用<Dropdown> <Dropdown.Button /> <Dropdown.Menu> <li>选项1</li> <li>选项2</li> </Dropdown.Menu></Dropdown>优势:状态管理集中,协作逻辑透明;局限:需合理设计子组件API。
自定义Hook将状态逻辑提取为独立函数,实现跨组件复用。例如,封装窗口尺寸监听:
const useWindowSize = () => { const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight }); useEffect(() => { const handleResize = () => setSize({ width: window.innerWidth, height: window.innerHeight }); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); return size;};// 使用function App() { const { width, height } = useWindowSize(); return <p>窗口尺寸:{width} x {height}</p>;}优势:代码简洁、易于测试,是React官方推荐的逻辑复用方式;局限:需避免过度拆分导致逻辑碎片化。
选择建议: