
React 组件的核心是从 Model(state 和 props)到 View 的映射。这种映射过程可以通过 JSX 声明式地描述,而 React 负责处理 DOM 变化的细节。数据绑定机制确保 Model 变化时 UI 自动更新。
Class 组件在 React 中存在两个关键问题:
函数组件更自然地描述 State => View 的映射,但早期存在局限性:
Hooks 的出现是为了解决函数组件的局限性,其核心思想是将外部数据绑定到函数执行。当数据变化时,函数重新执行并更新 UI。Hooks 的本质是将目标结果(如 DOM 树)与数据源或事件源(如 state、URL、窗口大小)挂钩。
Hooks 的命名源于其“钩子”机制:
Hooks 不仅适用于 React,其思想可泛化到其他场景。
Hooks 最大的价值是简化逻辑复用。以监听窗口大小变化为例,对比 Class 组件和 Hooks 的实现:
const withWindowSize = Component => {
class WrappedComponent extends React.PureComponent {
// 监听窗口大小并传递给子组件
state = { size: this.getSize() };
componentDidMount() { window.addEventListener("resize", this.handleResize); }
componentWillUnmount() { window.removeEventListener("resize", this.handleResize); }
getSize = () => window.innerWidth > 1000 ? "large" : "small";
handleResize = () => this.setState({ size: this.getSize() });
render() { return <Component size={this.state.size} />; }
}
return WrappedComponent;
};
// 使用高阶组件
class MyComponent extends React.Component {
render() {
const { size } = this.props;
return size === "small" ? <SmallComponent /> : <LargeComponent />;
}
}
export default withWindowSize(MyComponent);function useWindowSize() {
const [size, setSize] = useState(() => window.innerWidth > 1000 ? "large" : "small");
useEffect(() => {
const handleResize = () => setSize(window.innerWidth > 1000 ? "large" : "small");
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return size;
}
// 直接使用 Hook
function MyComponent() {
const size = useWindowSize();
return size === "small" ? <SmallComponent /> : <LargeComponent />;
}