在 React 中,Hooks 是一种在函数组件中使用状态和其他 React 特性(如生命周期方法)的新方式。它们在 React 16.8 中被引入,而且极大简化了组件的状态管理和副作用处理。
常见的 React Hook
- useState
- useEffect
- useContext
- useReducer
- useRef
- useMemo
- useCallback
- useLayoutEffect
- useImperativeHandle
1. useState
useState 是最基本的 Hook,用于在函数组件中添加状态。
示例:
- import React, { useState } from 'react';
- function Counter() {
- const [count, setCount] = useState(0); // count 为状态变量,setCount 为更新该状态的函数
- return (
- <div>
- <p>You clicked {count} times</p>
- <button onClick={() => setCount(count + 1)}>Click me</button>
- </div>
- );
- }
- export default Counter;
复制代码
- useState(0) 中的 0 是初始状态值。
- setCount 是更新状态的方法。
2. useEffect
useEffect 用于处理副作用,雷同于类组件中的生命周期方法(如 componentDidMount, componentDidUpdate, componentWillUnmount)。
示例:
- import React, { useState, useEffect } from 'react';
- function Example() {
- const [count, setCount] = useState(0);
- // 组件挂载时运行
- useEffect(() => {
- console.log('Component mounted or count changed!');
- document.title = `You clicked ${count} times`;
- // 返回的函数是清理函数,在组件卸载时调用
- return () => {
- console.log('Cleanup for count change!');
- };
- }, [count]); // 依赖数组,表示只有当 count 改变时才执行副作用
- return (
- <div>
- <p>You clicked {count} times</p>
- <button onClick={() => setCount(count + 1)}>Click me</button>
- </div>
- );
- }
- export default Example;
复制代码
- useEffect 第一个参数是一个副作用函数,第二个参数是依赖数组。
- 假如依赖数组为空([]),副作用函数只会在组件挂载和卸载时执行。
3. useContext
useContext 用于在函数组件中访问 React 上下文(Context)中的值。
示例:
- import React, { useContext } from 'react';
- // 创建上下文
- const MyContext = React.createContext('default value');
- function Example() {
- const value = useContext(MyContext); // 访问上下文值
- return <div>{value}</div>;
- }
- function App() {
- return (
- <MyContext.Provider value="Hello, world!">
- <Example />
- </MyContext.Provider>
- );
- }
- export default App;
复制代码
- useContext(MyContext) 用于获取 MyContext 提供的值。
4. useReducer
useReducer 是一种更复杂的状态管理方式,雷同于 useState,但是它适用于处理复杂的状态逻辑,尤其是有多个子状态的情况。它通常用于处理复杂的状态更新逻辑,大概在 React 应用中使用雷同 Redux 的模式。
示例:
- import React, { useReducer } from 'react';
- // 定义 reducer 函数
- function counterReducer(state, action) {
- switch (action.type) {
- case 'increment':
- return { count: state.count + 1 };
- case 'decrement':
- return { count: state.count - 1 };
- default:
- return state;
- }
- }
- function Counter() {
- const [state, dispatch] = useReducer(counterReducer, { count: 0 });
- return (
- <div>
- <p>Count: {state.count}</p>
- <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
- <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
- </div>
- );
- }
- export default Counter;
复制代码
- useReducer 接受两个参数:reducer 函数和初始状态。
- dispatch 是用于触发 reducer 更新状态的函数。
5. useRef
useRef 用于获取 DOM 元素的引用大概恒久化值。在重新渲染时,useRef 不会导致组件重新渲染,它常用于访问 DOM 元素或保持跨渲染周期不变的值。
示例:
- import React, { useRef } from 'react';
- function FocusInput() {
- const inputRef = useRef();
- const focusInput = () => {
- inputRef.current.focus(); // 让 input 元素获取焦点
- };
- return (
- <div>
- <input ref={inputRef} type="text" />
- <button onClick={focusInput}>Focus the input</button>
- </div>
- );
- }
- export default FocusInput;
复制代码
- useRef 返回一个对象,该对象的 current 属性指向 DOM 元素或任何可变值。
6. useMemo
useMemo 用于缓存计算结果,以制止不必要的重新计算。它只会在依赖项发生变化时重新计算结果。
示例:
- import React, { useMemo } from 'react';
- function Example({ num }) {
- const expensiveComputation = (num) => {
- console.log('Computing...');
- return num * 2;
- };
- const computedValue = useMemo(() => expensiveComputation(num), [num]);
- return <div>{computedValue}</div>;
- }
- export default Example;
复制代码
- useMemo 通过依赖数组来优化性能,制止在每次渲染时执行高昂的计算。
7. useCallback
useCallback 用于返回一个 memoized 版本的回调函数,只有当依赖项发生变化时才会更新。它常用于将回调函数通报给子组件,以制止不必要的重新渲染。
示例:
- import React, { useCallback, useState } from 'react';
- function Button({ onClick }) {
- return <button onClick={onClick}>Click me</button>;
- }
- function Parent() {
- const [count, setCount] = useState(0);
- const increment = useCallback(() => setCount(count + 1), [count]);
- return (
- <div>
- <Button onClick={increment} />
- <p>Count: {count}</p>
- </div>
- );
- }
- export default Parent;
复制代码
- useCallback 确保 increment 函数只有在 count 改变时才会重新创建。
8. useLayoutEffect
useLayoutEffect 和 useEffect 雷同,差别之处在于它会在 DOM 更新之前同步执行。通常用于读取结构和同步触发副作用。
示例:
- import React, { useLayoutEffect, useState } from 'react';
- function LayoutExample() {
- const [width, setWidth] = useState(0);
- useLayoutEffect(() => {
- setWidth(window.innerWidth);
- }, []);
- return <div>Window width: {width}</div>;
- }
- export default LayoutExample;
复制代码
- useLayoutEffect 在 DOM 更新后立即执行,通常用于在页面渲染之前进行一些丈量。
9. useImperativeHandle
useImperativeHandle 用于自定义暴露给父组件的实例值。通常与 forwardRef 共同使用,用于在函数组件中暴露 ref。
示例:
- import React, { useImperativeHandle, forwardRef, useRef } from 'react';
- const MyComponent = forwardRef((props, ref) => {
- const localRef = useRef();
- useImperativeHandle(ref, () => ({
- focus: () => {
- localRef.current.focus();
- }
- }));
- return <input ref={localRef} />;
- });
- function Parent() {
- const inputRef = useRef();
- const focusInput = () => {
- inputRef.current.focus(); // 使用子组件暴露的 focus 方法
- };
- return (
- <div>
- <MyComponent ref={inputRef} />
- <button onClick={focusInput}>Focus the input</button>
- </div>
- );
- }
- export default Parent;
复制代码
- useImperativeHandle 用于控制外部组件访问的实例值。
总结
React 的 Hook 提供了许多强大的功能,使函数组件可以或许处理状态、生命周期、引用等。掌握这些常用的 Hook,可以或许帮助你在开辟中写出更加简便、可维护的代码。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |