如何封装react组件
封装React组件的基本原则
封装React组件需要遵循高内聚、低耦合的设计原则,确保组件功能独立且易于维护。组件的封装通常包括props定义、状态管理、样式隔离和逻辑复用等方面。
定义清晰的props接口
使用TypeScript或PropTypes明确组件接受的props类型和默认值。这能提升代码可读性和维护性。
import PropTypes from 'prop-types';
function Button({ text, onClick, disabled }) {
return (
<button onClick={onClick} disabled={disabled}>
{text}
</button>
);
}
Button.propTypes = {
text: PropTypes.string.isRequired,
onClick: PropTypes.func,
disabled: PropTypes.bool,
};
Button.defaultProps = {
disabled: false,
onClick: () => {},
};
状态管理与副作用隔离
将组件内部状态与业务逻辑分离,复杂状态管理推荐使用自定义Hook。
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(c => c + 1);
const decrement = () => setCount(c => c - 1);
return { count, increment, decrement };
}
function Counter() {
const { count, increment } = useCounter();
return <button onClick={increment}>{count}</button>;
}
样式封装方案
采用CSS Modules或styled-components实现样式作用域隔离。
import styles from './Button.module.css';
function Button() {
return <button className={styles.primary}>Click</button>;
}
或使用styled-components:
import styled from 'styled-components';
const StyledButton = styled.button`
background: ${props => props.primary ? 'blue' : 'gray'};
`;
function Button({ primary }) {
return <StyledButton primary={primary}>Click</StyledButton>;
}
组件组合与children用法
利用children prop实现灵活的内容组合,避免过度嵌套。
function Card({ title, children }) {
return (
<div className="card">
<h2>{title}</h2>
<div className="content">{children}</div>
</div>
);
}
// 使用
<Card title="Profile">
<Avatar />
<UserInfo />
</Card>
高阶组件与Render Props
对于跨组件逻辑复用,可选择高阶组件或render props模式。
高阶组件示例:
function withLoading(WrappedComponent) {
return function({ isLoading, ...props }) {
return isLoading ? <Spinner /> : <WrappedComponent {...props} />;
};
}
Render Props示例:
function DataFetcher({ children }) {
const [data, setData] = useState(null);
useEffect(() => {
fetchData().then(setData);
}, []);
return children(data);
}
// 使用
<DataFetcher>
{data => data && <List items={data} />}
</DataFetcher>
性能优化技巧
使用React.memo避免不必要的渲染,配合useCallback缓存事件处理函数。
const MemoButton = React.memo(function Button({ onClick, text }) {
return <button onClick={onClick}>{text}</button>;
});
function Parent() {
const handleClick = useCallback(() => {
console.log('Clicked');
}, []);
return <MemoButton onClick={handleClick} text="Click" />;
}
组件文档与示例
为组件编写清晰的文档和示例代码,可使用Storybook等工具建立组件库。
// Button.stories.js
export default {
title: 'Components/Button',
component: Button,
};
const Template = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
text: 'Primary Button',
primary: true,
};






