Day 12:组件模式
HOC(高阶组件)
接收组件,返回增强后的组件
function withLoading(Component) {
return function WithLoading({ isLoading, ...props }) {
if (isLoading) return <Loading />;
return <Component {...props} />;
};
}
const EnhancedComponent = withLoading(MyComponent);
Render Props
把"怎么渲染"交给子组件决定
class MouseTracker extends React.Component {
state = { x: 0, y: 0 };
render() {
return (
<div onMouseMove={e => this.setState({ x: e.clientX, y: e.clientY })}>
{this.props.render(this.state)}
</div>
);
}
}
// 使用
<MouseTracker render={({ x, y }) => <h1>{x}, {y}</h1>} />
// Hook 写法
function useMouse() {
const [pos, setPos] = useState({ x: 0, y: 0 });
useEffect(() => {
const handler = e => setPos({ x: e.clientX, y: e.clientY });
window.addEventListener('mousemove', handler);
return () => window.removeEventListener('mousemove', handler);
}, []);
return pos;
}
组合模式
用 props 组合,简单灵活
function Card({ header, children, footer }) {
return (
<div className="card">
<div className="header">{header}</div>
<div className="body">{children}</div>
<div className="footer">{footer}</div>
</div>
);
}
自定义 Hook
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
面试问题
| 问题 | 答案要点 |
|---|---|
| HOC vs Hook? | HOC 包装组件,Hook 抽象逻辑 |
| render props 缺点? | 嵌套地狱,Hook 更好 |
| 组合vs继承? | 优先组合 |