Component reuse strategy
Component development standards and reuse strategies are crucial parts of front-end engineering, directly impacting project maintainability and development efficiency. Well-designed component specifications reduce redundant work and improve team collaboration quality, while rational reuse strategies maximize code value.
Component Design Principles
Single Responsibility Principle
Each component should address only one specific problem. For example, a button component should handle only click interactions, not business logic:
// Not recommended: Mixing business logic
function OrderButton() {
const handleClick = () => {
fetch('/api/order').then(/*...*/)
}
return <button onClick={handleClick}>Place Order</button>
}
// Recommended: Pure UI component
function Button({ onClick, children }) {
return <button onClick={onClick}>{children}</button>
}
Controlled vs. Uncontrolled Design
Clearly distinguish component state management approaches:
- Controlled components: State fully managed by parent components
- Uncontrolled components: Maintain their own internal state
// Controlled input
function ControlledInput({ value, onChange }) {
return <input value={value} onChange={onChange} />
}
// Uncontrolled input
function UncontrolledInput({ defaultValue }) {
const [value, setValue] = useState(defaultValue)
return <input value={value} onChange={e => setValue(e.target.value)} />
}
Interface Specifications
Props Design Guidelines
- Use TS/PropTypes to explicitly define types
- Boolean props should be prefixed with
is
/has
- Event callback props should use the
on
prefix
interface ModalProps {
isOpen: boolean
title: string
onClose: () => void
children?: React.ReactNode
}
Default Values and Required Props
Handle optional props with default parameters:
function Avatar({ size = 'medium', src }) {
const sizes = {
small: 32,
medium: 48,
large: 64
}
return <img width={sizes[size]} src={src} />
}
Styling Solutions
CSS Scoping Isolation
Recommended solutions in order of priority:
- CSS Modules
- Styled Components
- Scoped CSS
/* Button.module.css */
.primary {
background: #1890ff;
color: white;
}
import styles from './Button.module.css'
function Button({ type }) {
return <button className={styles[type]} />
}
Component Reuse Patterns
Higher-Order Components (HOC)
Suitable for cross-cutting concerns:
function withLoading(Component) {
return function WrappedComponent({ isLoading, ...props }) {
return isLoading ? <Spinner /> : <Component {...props} />
}
}
const EnhancedTable = withLoading(DataTable)
Render Props
Provides more flexible reuse:
<MouseTracker>
{({ x, y }) => (
<div>Current mouse position: {x}, {y}</div>
)}
</MouseTracker>
Documentation and Examples
Storybook Integration
Create visual documentation for each component:
// Button.stories.js
export default {
title: 'Components/Button',
component: Button
}
export const Primary = () => <Button type="primary">Submit</Button>
Version Management and Updates
Semantic Versioning
Component libraries should follow MAJOR.MINOR.PATCH
principles:
- MAJOR: Breaking changes
- MINOR: Backward-compatible feature additions
- PATCH: Bug fixes
Changelog Standards
Each version update should include:
- New features
- Bug fixes
- Breaking change notices
## [1.2.0] - 2023-05-20
### Added
- Button component now supports loading state
### Fixed
- Fixed memory leak in Modal component
Performance Optimization Strategies
Memoization
Cache complex computations:
const MemoizedComponent = React.memo(function MyComponent({ list }) {
const sortedList = useMemo(() => {
return list.sort(/* Complex computation */)
}, [list])
return <div>{sortedList.map(/*...*/)}</div>
})
Virtual Scrolling Implementation
Handle large data rendering:
function VirtualList({ items, itemHeight, renderItem }) {
const [startIndex, setStartIndex] = useState(0)
const visibleCount = Math.ceil(window.innerHeight / itemHeight)
return (
<div style={{ height: items.length * itemHeight }}>
{items.slice(startIndex, startIndex + visibleCount).map((item, i) => (
<div key={i} style={{ position: 'absolute', top: (startIndex + i) * itemHeight }}>
{renderItem(item)}
</div>
))}
</div>
)
}
Testing Strategies
Unit Test Coverage
Use Jest + Testing Library:
test('Button triggers callback on click', () => {
const handleClick = jest.fn()
render(<Button onClick={handleClick} />)
fireEvent.click(screen.getByRole('button'))
expect(handleClick).toHaveBeenCalled()
})
Visual Regression Testing
Implement with Storybook + Chromatic:
npx chromatic --project-token=<your_token>
Multi-Platform Adaptation
Responsive Design
Use CSS media queries:
@media (max-width: 768px) {
.container {
flex-direction: column;
}
}
Conditional Rendering
Render different content based on device features:
function ResponsiveComponent() {
const isMobile = useMediaQuery('(max-width: 768px)')
return isMobile ? <MobileView /> : <DesktopView />
}
Internationalization Support
Multi-Language Component Design
Provide language packs via context:
const I18nContext = createContext()
function App() {
const [locale, setLocale] = useState('zh-CN')
return (
<I18nContext.Provider value={locale}>
<Navbar onChangeLanguage={setLocale} />
<Content />
</I18nContext.Provider>
)
}
function useTranslation() {
const locale = useContext(I18nContext)
return key => translations[locale][key]
}
Theming Solutions
CSS Variable Control
Implement dynamic theme switching:
:root {
--primary-color: #1890ff;
--text-color: #333;
}
.dark {
--primary-color: #177ddc;
--text-color: #eee;
}
function ThemeToggle() {
const [isDark, setIsDark] = useState(false)
useEffect(() => {
document.body.className = isDark ? 'dark' : ''
}, [isDark])
return <Switch checked={isDark} onChange={setIsDark} />
}
Component Classification System
Atomic Design Methodology
Establish clear component hierarchy:
- Atoms: Basic elements like buttons, inputs
- Molecules: Combinations like search bar = input + button
- Organisms: Complex structures like navbar = logo + menu + user panel
- Templates: Page skeleton layouts
- Pages: Specific business pages
Code Splitting Strategies
Dynamic Component Importing
Load on demand for better performance:
const HeavyComponent = React.lazy(() => import('./HeavyComponent'))
function App() {
return (
<Suspense fallback={<Spinner />}>
<HeavyComponent />
</Suspense>
)
}
Error Boundary Handling
Component-Level Error Catching
Prevent local UI crashes from affecting the whole:
class ErrorBoundary extends React.Component {
state = { hasError: false }
static getDerivedStateFromError() {
return { hasError: true }
}
render() {
if (this.state.hasError) {
return <FallbackUI />
}
return this.props.children
}
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn