解释在React v16.8中引入的React hooks的新特性
React v16.8 对于所有React开发者来说都是一个奇迹,因为这个版本的React向我们所有人引入了 hooks 。在它发布之前,开发者社区已经厌倦了使用类组件,但他们仍然不得不使用类组件,因为函数组件没有提供类组件提供的许多功能。但是在使用hooks后,我们可以在函数组件中使用那些只能通过类组件访问的功能。所以我们可以说在这个版本React v16.8之后,类组件的流行度降低了。
Hooks : 它们就像是函数,可以帮助你从函数组件中连接到React的状态和生命周期。Hooks不能与类组件一起使用,它只能在函数组件中使用。
Hooks只能在任何函数组件的顶部调用。绝对不要尝试在任何条件、循环或嵌套函数中调用hooks。Hooks可以很容易地在任何函数组件内部识别,因为它们以”use”关键字开头。
有两种类型的Hooks:
- 内置Hooks: 这些是内置的Hooks,我们只需使用它们来利用它们的功能。一些内置hooks的示例是”useEffect”, “useMemo”, “useRef”等…
- 自定义hooks: 它只是一个以”use”关键字开头的javascript函数,并且可以调用其他hooks。换句话说,自定义hooks是我们必须创建的hooks来获得所需的功能。
现在,为了使用hooks,我们必须在希望使用hooks的文件中导入hooks。
语法:
- 导入内置hooks:
import { hook1,hook2,hook3.... } from 'react';
在这里,“hook1,hook2,hook3………”表示以逗号分隔的不同的hooks,您想要在您的React组件中导入。
- 导入自定义hooks:
import HookName from 'filepath';
“HookName”是自定义hook的名称,“filepath”是该hook所在文件的位置
创建React应用程序: 在使用hook之前,我们需要创建并启动我们的React应用程序。
步骤1: 使用以下命令创建一个React应用程序:
npx create-react-app reacthook
步骤2: 在创建您的项目文件夹(即reacthook)之后,使用此命令进入它:
cd reacthook
项目结构: 它将会像下面这样。
在此之后,使用以下命令运行您的应用程序:
npm start
React v16.8中的新功能:
1. Hooks允许我们在函数组件内部使用State:
我们都知道React State。它与任何变量相比具有很大的优势,因为如果变量发生变化,则组件不会重新渲染,但是如果状态发生变化,则整个组件会重新渲染。
在React v16.8之前,我们只能在类组件中使用状态,因为那里内置了“state”对象。但是在这个版本之后,函数组件也可以通过 “useState” hook使用状态。
语法:
let [current state, function] = useState(Initial value of that state);
示例: 在下面的示例中,我们创建了一个状态“work”,其初始值为“learning”,并在按钮点击时更改了该值。由于它是一个状态且其值改变了,所以它重新渲染了整个组件,我们可以看到更新后的值。
import "./App.css";
import { useState } from "react";
function App() {
let [work, setWork] = useState("Learning");
function updateWork() {
setWork("Learning from GFG");
}
return (
<div className="App">
<header className="App-header">
<h1 className="gfg">GeeksforGeeks</h1>
<h3 className="gfghook">
State in Functional Component
</h3>
<h3>{work}</h3>
<button onClick={updateWork}>Click Here</button>
</header>
</div>
);
}
export default App;
输出:
2. Hooks帮助我们在函数组件中使用React的生命周期特性:
有一个叫做“ useEffect ”的钩子,它帮助我们获取React生命周期特性,这在类组件中是唯一可用的。“useEffect”钩子就像是“componentDidMount”、“componentDidUpdate”和“componentWillUnmount”的组合。这意味着这个钩子将在组件挂载、更新和卸载之前被调用。
语法:
useEffect(function,array of dependencies)
注意: 这里的依赖数组是可选的
示例: 在下面给出的示例中,useEffect钩子在组件挂载时被调用,之后每当更新该组件时,它都会被调用多次。
import "./App.css";
import { useState, useEffect } from "react";
function App() {
let [count, setCount] = useState(0);
function updateCount() {
setCount((count = count + 1));
}
useEffect(() => {
console.log("Component is mounted,updated or unmounted");
});
return (
<div className="App">
<header className="App-header">
<h1 className="gfg">GeeksforGeeks</h1>
<h3 className="gfghook">
LifeCycle features in Functional Component</h3>
<h3>Count is {count}</h3>
<button onClick={updateCount}>Click Here</button>
</header>
</div>
);
}
export default App;
输出:
注意: 在React 18中,当我们在“index.js”文件中使用“StrictMode”时,“useEffect”在挂载时会被调用两次。所以由于我们在“index.js”文件中使用了“StrictMode”,所以我们会得到相应的输出。
3. Hooks帮助我们在功能组件中使用纯组件功能:
假设有一个包含任何值的状态,假设为0。现在有一个函数,用于更新状态的值,但是状态的新值和前一个值保持相同。这意味着该函数用0替换了0。在这种情况下,组件将重新渲染,因为状态已更新。
但实际上,更新后的值与先前的值相同。所以重新渲染没有任何好处。因此,React有一个称为纯组件的组件,它将前一个状态和属性的值与更新后的值进行比较。如果更新后的值与先前的值相同,则不会重新渲染组件;如果更新后的值与先前的值不同,则会重新渲染组件。
但在React v16.8之前,只能在类组件中访问纯组件的这个功能,但现在我们可以通过“ useMemo ”hook在功能组件中访问此功能。
语法:
useMemo(function,array of dependencies)
useMemo钩子函数在组件挂载时第一次被调用,然后在其依赖项实际更新时再次被调用,这意味着其之前的值与更新后的值不同。
现在我们将从useMemo中返回组件的代码,我们只想在任何依赖项实际更新时重新渲染该组件。返回后,我们将其存储在任何变量中,并将其放置在函数组件的返回语句中。
示例:
import "./App.css";
import { useState, useMemo } from "react";
function App() {
let [count, setCount] = useState(0);
function updateCount() {
setCount((count = count + 1));
}
let a = useMemo(() => {
console.log("State really got updated");
return (
<>
<h1 className="gfg">GeeksforGeeks</h1>
<h3 className="gfghook">
Pure Component features in Functional Component
</h3>
<h3>Count is {count}</h3>
<button onClick={updateCount}>Click Here</button>
</>
);
}, [count]);
return (
<div className="App">
<header className="App-header">{a}</header>
</div>
);
}
export default App;
输出:
4. Hooks帮助我们操纵DOM
早先,React中通过createRef()方法来操作DOM只能在类组件中完成。但自从React v16.8之后,我们可以通过”useRef” hook来操纵DOM。
语法:
useRef(initial value)
对于DOM操作,我们应该将useRef初始化为null并将其存储在任何变量中。之后,无论我们在哪里使用该useRef,我们只需简单地写:
ref={variable name in which useRef is stored}
因此,在下面的示例中,我们将通过输入字段来操作DOM,因此在输入字段中添加了ref={myref}。
然后,我们使用”useRef”在一个函数中添加了功能,以在该输入字段中显示”1000″,并使该输入字段的背景颜色变为黄色。然后,我们在按钮点击时调用了该函数。
示例:
import "./App.css";
import { useRef } from "react";
function App() {
let myref = useRef(null);
function handleDOM() {
myref.current.value = 1000;
myref.current.style.backgroundColor = "yellow";
}
return (
<div className="App">
<header className="App-header">
<h1 className="gfg">GeeksforGeeks</h1>
<h3 className="gfghook">
DOM Manipulation in Functional Component</h3>
<input type="text" ref={myref}></input>
<button onClick={handleDOM}>Click Here</button>
</header>
</div>
);
}
export default App;
输出: