什么是钩子,我们什么时候使用它们?
如果我们想在创建 React Web 应用程序时制作功能组件,Hooks 是 React 为我们提供的功能。这些功能是一些生命周期方法(如 componentDidMount()、componentDidUpdate())的替代品,除此之外,它还为我们提供了编写可维护代码的更大灵活性。使用钩子而不是基于类的组件的一个主要原因是,当应用程序的复杂性增加时,理解基于类的组件并使用它们可能会变得困难或具有挑战性。
在本文中,我们将了解 react 中的 hooks 并为您介绍它们。
必须知道的钩子:
React useState() 钩子:这个钩子有助于维护组件状态。它接受一个称为初始状态的参数,它是组件状态的默认值。它返回两个属性:组件状态,以及我们可以用来更新组件状态的函数。例如,在下面给出的代码中,我们已经解构了 state 和 setState(我们可以将它们命名为任何东西,不一定是state和setState ),
const [state,setState] = useState({});
反应 useEffect() 钩子: 这个钩子接受一个函数作为第一个参数,一个依赖数组作为第二个参数。这个钩子类似于componentDidMount() 和componentDidUpdate(),即只要组件第一次渲染和组件状态更新,该函数就会运行。为了只运行一次参数函数(在渲染组件时),我们必须使依赖数组为空。但是,如果我们希望在某个对象、属性或变量发生变化时渲染函数,那么我们需要将它传递给依赖数组。此外,由于它是一个数组,我们可以传递多个值。在下面给出的代码中考虑有一个可变的变量input 。每当输入变量发生变化时,匿名函数将在控制台中打印“welcome to geeks for geeks”。
useEffect(() => { console.log("welcome to geeks for geeks"); }, [input])
React useRef() 钩子:这个钩子主要帮助我们做两件事:跟踪输入或状态变化,以及获取 DOM 节点的引用。它返回一个具有当前属性的对象,并保存我们想要跟踪的值。在下面的代码中,我们稍后在某些代码中使用 useRef 访问 DOM 节点(输入)。
const stateRef = useRef(); // some code ...
现在我们将做一个小项目,以了解它们如何在 React 应用程序中协同工作。
创建反应应用程序:
第 1 步:使用以下命令创建一个 React 应用程序。
npx create-react-app foldername
第 2 步:创建项目文件夹(即函数演示)后,使用以下命令移动到该文件夹。
cd foldername
第 3 步:安装 Axios 作为依赖项。
npm install axios
第 4 步:运行开发服务器。
npm start
项目结构:
实现:在相应的文件中写下以下代码。
App.js:在这个组件中,我们将使用useState()和useRef()钩子。在useState()的帮助下,我们将创建一个组件状态,它将是用户想要查找天气信息的城市或地点。我们添加了基本样式,为输入字段设置了一个匿名 onChange函数,该函数将更新 inputRef.current 的值,一个handleClick()函数负责在用户单击按钮时更新状态。这里我们将 inputRef 的默认值设置为 null。另外,请注意,我们已通过location的属性名称将 App 组件的状态传递给WeatherDataComponent() 。
App.js
import "./App.css";
import { useState, useRef } from "react";
import WeatherData from "./Components/WeatherComponent";
function App() {
const [state, setstate] = useState("");
const inputRef = useRef(null);
const handleClick = () => {
setstate(inputRef.current);
};
return (
(inputRef.current =
e.target.value)}
style={{
outline: "none",
border: "none",
borderBottom: "1px solid
rgb(110, 204, 113)",
margin: ".5rem",
}}
placeholder="Enter City"
/>
);
}
export default App;
WeatherComponent.js
import React, { useState, useEffect } from "react";
import axios from "axios";
const WeatherComponent = ({ location }) => {
const [weatherData, setWeatherData] = useState(null);
useEffect(() => {
const fetchData = async () => {
if (location === undefined || location === null || location.length === 0)
location = "Delhi";
var options = {
method: "GET",
url: "https://weatherapi-com.p.rapidapi.com/forecast.json",
params: { q: location, days: "2" },
headers: {
"x-rapidapi-host": "weatherapi-com.p.rapidapi.com",
"x-rapidapi-key":
"ffc2438edbmsh0a88b634e6e77a7p123125jsnfb163d4d72f7",
},
};
const response = await axios.request(options);
console.log("response.data", response.data);
setWeatherData(response.data);
};
fetchData();
}, [location]);
let displayData = "Loading...";
if (weatherData !== null && weatherData !== undefined) {
displayData = (
Weather Info
Region: {weatherData.location.region}
Whether:
{weatherData.forecast.forecastday[0].day.condition.text}
Date:
{weatherData.forecast.forecastday[0].date}{" "}
Whether:
{weatherData.forecast.forecastday[1].day.condition.text}
Date:
{weatherData.forecast.forecastday[1].date}{" "}
);
}
return <>{displayData}>;
};
export default WeatherComponent;
WeatherComponent.js:在这个组件中,我们使用了 useEffect() 钩子和 useState()。这里的组件状态是我们从 RapidAPI 获取的天气数据对象,您可以在选项对象中查看详细信息。我们为这个组件添加了一些基本样式。现在我们已经创建了 weatherData 对象的状态,它的变异函数,并通过 useState() 钩子将其初始化为 null。而我们在 useEffect() 中传递了一个匿名函数,该函数首先定义了一个异步 fetchData函数,然后调用它。另外,请注意,我们不能使 useEffect 的参数函数异步,因此我们定义了一个单独的函数来从 API 获取数据。首先,我们刚刚进行了边缘案例的检查,如果位置未定义或为空或长度为 0,那么默认情况下位置的值应该是德里。借助 setWeatherData函数获取数据后,我们将组件状态更新为用户输入城市名称的天气数据对象。另外,请注意依赖数组中有一个元素,因为我们不希望 useEffect 只运行一次,而是在从父组件传递的 location 属性更改时运行。
WeatherComponent.js
import React, { useState, useEffect } from "react";
import axios from "axios";
const WeatherComponent = ({ location }) => {
const [weatherData, setWeatherData] = useState(null);
useEffect(() => {
const fetchData = async () => {
if (location === undefined || location === null || location.length === 0)
location = "Delhi";
var options = {
method: "GET",
url: "https://weatherapi-com.p.rapidapi.com/forecast.json",
params: { q: location, days: "2" },
headers: {
"x-rapidapi-host": "weatherapi-com.p.rapidapi.com",
"x-rapidapi-key":
"ffc2438edbmsh0a88b634e6e77a7p123125jsnfb163d4d72f7",
},
};
const response = await axios.request(options);
console.log("response.data", response.data);
setWeatherData(response.data);
};
fetchData();
}, [location]);
let displayData = "Loading...";
if (weatherData !== null && weatherData !== undefined) {
displayData = (
Weather Info
Region: {weatherData.location.region}
Whether:
{weatherData.forecast.forecastday[0].day.condition.text}
Date:
{weatherData.forecast.forecastday[0].date}{" "}
Whether:
{weatherData.forecast.forecastday[1].day.condition.text}
Date:
{weatherData.forecast.forecastday[1].date}{" "}
);
}
return <>{displayData}>;
};
export default WeatherComponent;
输出:输出将如下所示。
说明:在这个反应应用程序中,我们使用了上述三个钩子及其同时工作。首先,默认情况下,用户将登陆应用程序,将获取与德里相关的天气数据,并且 WeatherData 组件的状态将更新为德里的天气数据对象。如果用户在输入中输入任何城市的名称并单击按钮,则 App 组件的状态将更新为输入的值,并将作为位置属性传递给 WeatherData 组件。然后由于依赖数组,useEffect 的函数将再次运行并获取指定位置的天气数据,从而更新 WeatherComponent 的状态。
输出: