前言
在前端当中的,React框架拥有较高的性能,代码逻辑非常简单,React 的核心是将一个页面拆分成多个独立的,可以复用的组件。但是类组件自身可能有各种状态,难以复用,所以就有Hooks这个概念了。
Hooks到底是什么?
hooks 的本质就是一类特殊的函数,为函数式组件注入特殊的功能
hooks 出现之前函数式组件的特点:
- 没有组件实例
- 没有生命周期
- 没有 state 和 setState,只能接受输入 props,输出 JSX
hooks 出现之前函数组件是一个纯函数,执行完即销毁,无法存储 state
于是 React 创造了 hooks 来增强函数式组件
Hooks都有哪些优点?
- 自定义 hooks 来复用状态,从而解决了类组件有些时候难以复用逻辑的问题
- 每调用 useHook 一次都会生成一份独立的状态,函数每次调用都会开辟一份独立的内存空间
- 虽然状态和副作用的存在依赖于组件,但它们可以在组件外部进行定义。这点是
class component
做不到的,你无法在外部声明state和副作用(如componentDidMount
)
常见的 hooks 函数
1. useState
作用:用于声明一个状态变量,并返回该变量和修改该变量的函数
使用方法:在函数组件中调用useState函数,传入初始值,返回一个数组,第一个元素是状态变量,第二个元素是修改该变量的函数
代码演示:
import React, { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}> Click me </button>
</div>
);
}
2. useEffect
作用:用于在函数组件中进行副作用操作,比如获取数据、订阅事件、修改DOM等
使用方法:在函数组件中调用useEffect函数,传入一个回调函数和一个依赖项数组,当依赖项数组发生变化时,执行回调函数
代码演示:
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
3. useCallback
作用:用于在函数组件中缓存函数以避免重复渲染
使用方法:在函数组件中调用useCallback函数,传入一个回调函数和依赖项数组,返回一个缓存后的回调函数
代码演示:
import React, { useState, useCallback } from 'react';
function ChildComponent({ onButtonClick }) {
// use useCallback to memoize the function
const handleClick = useCallback(() => {
console.log('Button clicked!');
onButtonClick();
}, [onButtonClick]);
return (
<div>
<button onClick={handleClick}>Click me</button>
</div>
);
}
function ParentComponent() {
const [count, setCount] = useState(0);
function handleButtonClick() {
setCount(count + 1);
}
return (
<div>
<p>Count: {count}</p>
<ChildComponent onButtonClick={handleButtonClick} />
</div>
);
}
4. useMemo
作用:用于在函数组件中缓存计算结果以避免重复计算。
使用方法:在函数组件中调用useMemo函数,传入一个回调函数和依赖项数组,返回一个缓存后的计算结果
代码演示:
import React, { useMemo } from 'react';
function ExpensiveCalculation({ a, b }) {
// use useMemo to memoize the result of the calculation
const result = useMemo(() => {
console.log('Calculating...');
return a + b;
}, [a, b]);
return <span>{result}</span>;
}
function MyComponent() {
return (
<div>
<ExpensiveCalculation a={4} b={6} />
</div>
);
}
5. useRef
作用:用于在函数组件中声明一个可变的引用变量
使用方法:在函数组件中调用useRef函数,传入初始值,返回一个可变的引用变量
代码演示:
import React, { useRef, useEffect } from 'react';
function TextInputWithFocusButton() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return (
<>
<input type="text" ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>Focus input</button>
</>
);
}
6. useContext
作用:用于在函数组件中使用全局上下文
使用方法:在函数组件中调用useContext函数,传入上下文对象,返回上下文值
代码演示:
import React, { useContext } from 'react';
import ThemeContext from '../contexts/ThemeContext';
function Header() {
const theme = useContext(ThemeContext);
return (
<header className={`header-${theme}`}>
<h1>My App</h1>
</header>
);
}
7. useReducer
作用:用于在函数组件中使用Reducer状态管理。
使用方法:在函数组件中调用useReducer函数,传入Reducer函数和初始值,返回一个数组,第一个元素是状态变量,第二个元素是dispatch函数
代码演示:
import React, { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<>
Count: {state.count}
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</>
);
}
8. useLayoutEffect
作用:与useEffect类似,但在DOM更新之前执行。
使用方法:在函数组件中调用useLayoutEffect函数,传入一个回调函数和依赖项数组,返回一个缓存后的计算结果
代码演示:
import React, { useLayoutEffect, useState } from 'react';
function Example() {
const [color, setColor] = useState('red');
// use useLayoutEffect to synchronously update the color
useLayoutEffect(() => {
document.body.style.backgroundColor = color;
}, [color]);
return (
<>
<p>The color is {color}</p>
<button onClick={() => setColor('red')}>Red</button>
<button onClick={() => setColor('green')}>Green</button>
<button onClick={() => setColor('blue')}>Blue</button>
</>
);
}
总结
React的Hooks函数有以下几个优点:
-
更容易编写和理解:使用Hooks函数可以让你更轻松地编写可重用的组件,并且避免了类组件中this关键字的问题。同时,Hooks函数也可以让你更好地组织代码,并且使代码更易于理解和维护。
-
更易于测试:使用Hooks函数可以更容易地编写单元测试,因为你可以更方便地使用模拟数据来测试组件。
-
更少的代码量:使用Hooks函数可以让你在不需要编写类的情况下使用状态和其它React特性,从而减少了代码量。
-
更好的性能:使用Hooks函数可以让你更好地控制副作用的执行时机,从而提高组件的性能。
-
更好的可读性:使用Hooks函数可以让你更好地组织代码,从而使代码更易于理解和维护。
总的来说,React的Hooks函数让你在函数组件中使用状态和生命周期方法,从而使代码更简洁、可读、可维护,同时也提高了组件的性能。
原文链接:https://juejin.cn/post/7236670763272781882 作者:Raise