react如何封装new 组件
封装 React 组件的基本方法
React 组件封装的核心思想是通过组合和抽象实现复用性。以下是封装组件的关键步骤:
定义组件接口
使用 props 明确组件接收的参数和类型,推荐结合 TypeScript 或 PropTypes:
interface ButtonProps {
children: React.ReactNode;
variant?: 'primary' | 'secondary';
onClick?: () => void;
}
实现基础结构 创建函数组件并处理基础逻辑:
const Button = ({ children, variant = 'primary', onClick }: ButtonProps) => {
return (
<button
className={`button-${variant}`}
onClick={onClick}
>
{children}
</button>
);
};
进阶封装技巧
复合组件模式
通过 children 或具名插槽实现灵活组合:
const Card = ({ header, content, footer }) => (
<div className="card">
{header && <div className="header">{header}</div>}
<div className="content">{content}</div>
{footer && <div className="footer">{footer}</div>}
</div>
);
// 使用示例
<Card
header={<h3>标题</h3>}
content={<p>正文内容</p>}
/>
HOC 高阶组件 扩展组件功能而不修改原组件:
const withLogger = (WrappedComponent) => {
return (props) => {
useEffect(() => {
console.log('组件已挂载');
}, []);
return <WrappedComponent {...props} />;
};
};
最佳实践建议
状态管理分离 将业务逻辑与 UI 解耦,使用自定义 Hook:
const useCounter = (initialValue = 0) => {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(v => v + 1);
return { count, increment };
};
// 组件内调用
const Counter = () => {
const { count, increment } = useCounter();
return <button onClick={increment}>{count}</button>;
};
上下文封装 对复杂层级使用 Context API:
const ThemeContext = createContext('light');
const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
};
性能优化方案
Memoization 技术 避免不必要的重新渲染:
const MemoizedComponent = React.memo(({ data }) => {
return <div>{data}</div>;
}, (prevProps, nextProps) => {
return prevProps.data === nextProps.data;
});
懒加载实现 配合 Suspense 实现代码分割:
const LazyComponent = React.lazy(() => import('./HeavyComponent'));
const App = () => (
<Suspense fallback={<Loader />}>
<LazyComponent />
</Suspense>
);
测试策略
单元测试配置 使用 Jest + Testing Library 编写测试用例:
test('Button renders correctly', () => {
render(<Button>Click</Button>);
expect(screen.getByText('Click')).toBeInTheDocument();
});
Storybook 集成 可视化开发组件库:
// Button.stories.js
export default {
title: 'Components/Button',
component: Button,
};
export const Primary = () => <Button variant="primary">Submit</Button>;






