了解React的Hook(初学者指南)
最近开始接触React作为学习的一部分,但由于出现了不熟悉的词汇和思维方式,感觉很困难,因此将它们总结下来以备忘。
虽然最初打算从React是什么开始写,但我只会留下关键的要点,以免自己忘记。
Reactフック是什么?
首先,React Hook(Hooks)是在React 16.8及其以后的版本中引入的功能,是用于在函数组件内部访问状态(state)和生命周期事件的API。通过使用Hook,可以在不使用类组件的情况下管理状态和处理副作用。
太难了。光听到这么一句话,我还是不明白,所以我会逐一解释。
“组件”的意思是什么?
组件是React应用程序的一部分,是用于创建屏幕上的元素(如按钮、文本框、图像等)的可重用代码块。通过使用组件,可以将应用程序的屏幕分解成小部件,并通过组装它们来创建整个屏幕。
例如,考虑一个购物网站的用户界面。可以将其分为头部、侧边栏、商品列表和页脚等几个部分。这些部分被单独创建为组件,并通过组合它们来构建整个页面的布局。
组件有两种类型:函数组件和类组件,但它们都用于相同的目的。函数组件可以用更简单、更短的代码编写,而类组件可以实现更复杂的功能。最近,使用React钩子,函数组件可以实现与类组件相同的功能,因此函数组件经常被使用。
简单来说,组件是React应用程序的小部件,用于创建可重复使用的代码并将它们组合以构建整个界面。
“ステート(state)”意指的是什么?
state是在组件内管理的数据。当state发生变化时,组件会重新渲染并显示基于新state值的内容。通过这样做,可以实现动态的用户界面。在函数组件中,可以使用useState钩子来管理state。
生命周期事件是指生命的各个阶段性事件。
生命周期是指React组件在应用程序中经历的一系列阶段或步骤。在React中,组件在显示、更新和销毁时会经过这些阶段。生命周期主要由以下三个阶段组成。
“挂载”(Mounting):这是组件首次添加到DOM的阶段。在这个阶段,组件会进行初始化和初始渲染。
更新:在这个阶段,通过重新渲染组件来反映状态和属性的变化。当状态或属性发生变化时,React会重新渲染组件,从而更新DOM。
卸载(Unmounting): 在此阶段,组件将被从 DOM 中移除。在这个阶段,与组件相关的资源将被清理和释放。
在函数组件中,可以使用 useEffect 钩子来实现对这些生命周期事件的逻辑处理。例如,可以使用 useEffect 来定义副作用,并返回一个清理函数,以控制在挂载、更新和卸载的每个阶段执行的处理过程。
以下是我經常使用的三種鉤子的選擇。
使用useState
让我们来看一个使用函数组件和useState的简单计数器应用程序示例。
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
export default Counter;
在这个示例中,我们创建了一个名为Counter的函数组件。我们使用useState钩子来定义一个名为count的状态变量和一个名为setCount的用于更新状态的函数。我们通过useState(0)将count的初始值设为0。
在return中的JSX中,显示当前计数值(count),并在点击按钮时使计数增加1。通过onClick事件,更新count为setCount(count + 1)。
这段代码中,count代表状态变量(state),setCount代表状态更新函数。当点击按钮时,count会被更新,组件将重新渲染,并显示最新的计数值。
通过使用函数组件和useState来管理状态,可以实现状态的变化导致UI的更新机制。
为什么有时候在 import React, { useState } from ‘react’; 中使用 {} 括起来,而有时候不使用?
在JavaScript的导入语法中,有两种方式:命名导入(Named imports)和默认导入(Default imports)。它们的使用方法和区别如下所示。
命名导入(Named imports):
使用{}是通过命名导入的方式。这是一种从模块中通过特定名称导入值的方法。在{}内指定要导入的名称。
例如:
import { useState, useEffect } from 'react';
在这个例子中,我们从 react 模块中导入了名为 useState 和 useEffect 的值。
默认导入(Default imports)是一种从模块中导入默认导出值的方法。无需使用{}进行导入。默认导出值只能存在一个。
我在家看电视。
在家的时候,我在观看电视。
import React from 'react';
在这个例子中,我正在导入从React模块默认导出的值(React对象)。
因此,在`import React, { useState } from ‘react’`这个语法中,我们同时从react模块中导入了默认导出的React对象和命名导入的useState函数。
模块是什么?
模块是构成JavaScript代码的单元。通过将代码分割为多个文件,并将其分别作为模块进行管理,可以提高代码的重用性、可读性和可维护性。模块具有独立的作用域,确保与其他模块的变量和函数名称不会发生冲突。
模块可以导出从其他模块中被使用的函数、变量、类等内容,并且可以从其他模块中导入所需的功能并使用。
模块的例子:
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
在这个math.js模块中,导出了add函数和subtract函数。
要在其他模块中使用math.js的函数,需要按照以下方式进行导入。
// app.js
import { add, subtract } from './math.js';
console.log(add(1, 2)); // 3
console.log(subtract(4, 1)); // 3
在这个app.js模块中,我从math.js模块导入了add函数和subtract函数,并使用它们。
组件和部件不同吗?
“雖然組件和模塊是不同的概念,但它們之間存在相關性。”
组件主要在React中表示UI的可重用组成部分。组件具有独立的功能,并通过与其他组件组合来构建更复杂的UI。在React中,可以以函数组件或类组件的形式实现。
模块是一种机制,用于管理和提高JavaScript代码的可重用性,它允许从其他文件中导入函数、变量、类等功能。模块不仅适用于React,而且可在JavaScript的整个范围内使用。
React组件与JavaScript模块的关联是指React组件也可以作为JavaScript模块进行导入和导出。换句话说,React组件被视为一种模块。
假设有一个如下所示的React组件。
// Button.jsx
import React from 'react';
const Button = (props) => {
return (
<button onClick={props.onClick}>{props.children}</button>
);
};
export default Button;
这个组件被导出为一个模块,可以从其他文件中导入并使用。
// App.jsx
import React from 'react';
import Button from './Button';
const App = () => {
const handleClick = () => {
alert('Button clicked!');
};
return (
<div>
<Button onClick={handleClick}>Click me</Button>
</div>
);
};
export default App;
理解React的人們應該知道,在React中,組件是UI的部件,而模塊則是JavaScript代碼的組成單位。
使用 useEffect
useEffect是React中的一个钩子,用于执行副作用(side effects)。
副作用(side effects)在编程中指的是函数或组件发生的与其主要目的无关的影响。主要包括对外部状态或变量产生影响的操作被称为副作用。
在React组件中,副作用可以包括以下内容。
1 从API获取数据
2 将数据存储到存储中
3 设置定时器和事件监听器
4 访问浏览器的localStorage
5 手动更改DOM
useEffect在函数组件中用于控制执行副作用的时机。传递给useEffect的函数将在组件挂载(首次渲染)、卸载(组件被销毁时),以及依赖关系发生变化时执行。
使用useEffect的示例。
import React, { useState, useEffect } from 'react';
function SimpleCounter() {
// カウントの状態を保持するstateを定義
const [count, setCount] = useState(0);
// カウントが変更されたときに実行される副作用を定義
useEffect(() => {
console.log('カウントが更新されました:', count); // 副作用: カウントが更新されたときにコンソールにログを出力
}, [count]); // 依存配列にcountを指定することで、countが変更されたときだけ実行される
return (
<div>
<p>現在のカウント: {count}</p> {/* countの値を表示 */}
<button onClick={() => setCount(count + 1)}>カウントアップ</button> {/* countを増やすボタン */}
</div>
);
}
export default SimpleCounter;
使用上下文
上下文是在React中通过组件树传递数据的方法,是为了方便将数据从父组件传递给子组件的机制。通过这种方式,可以共享数据而不使用props(从父组件传递给子组件的数据)。
useContext是React中的一个钩子函数,用于使用该上下文共享数据。
作为一个例子,我们可以创建一个ThemeContext,并使用它在App组件中向Child组件传递数据。在这个例子中,我们将从App组件向Child组件传递主题颜色。
首先,创建App.tsx文件,并编写以下代码。
// App.tsx
import React, { useState, useContext } from "react";
// 1. ThemeContextを作成
const ThemeContext = React.createContext("");
function App() {
// 2. テーマカラーをstateで管理
const [themeColor, setThemeColor] = useState("red");
return (
// 3. ThemeContext.Providerを使って、データを子コンポーネントに渡す
<ThemeContext.Provider value={themeColor}>
<Child />
<button onClick={() => setThemeColor("blue")}>Change theme color to blue</button>
</ThemeContext.Provider>
);
}
function Child() {
// 4. useContextフックを使って、データを受け取る
const themeColor = useContext(ThemeContext);
return (
// 5. 受け取ったデータを表示
<p>Theme color is: {themeColor}</p>
);
}
export default App;
添加说明。
1 使用React.createContext创建一个新的上下文对象。在这个例子中,我们将其命名为ThemeContext。
2 使用useState定义themeColor来管理主题颜色,并使用setThemeColor来更新它。初始值设为red。
3 使用ThemeContext.Provider组件将themeColor传递给子组件。可以通过value属性指定数据。
4 在Child组件中,使用useContext钩子从ThemeContext中接收数据。在这个例子中,我们接收themeColor。
5 显示接收到的数据(themeColor)。
运行此代码时,首先Child组件将显示为“Theme color is: red”。当点击按钮时,将调用setThemeColor并将主题颜色更改为blue,然后显示为“Theme color is: blue”。
顺便说一句,像ThemeContext.Provider这样在Provider上添加Provider是React上下文API的惯例。Provider的作用是“提供数据”。
虽然还有很多重要的事情要做,但我认为只要能稍微利用这个技巧,就能向进步更近一步。让我们每天努力吧。