React useEffect
Hooks
Hook cho phép bạn thực hiện các hiệu ứng useEffect
phụ trong các thành phần của bạn.
Một số ví dụ về tác dụng phụ là: tìm nạp dữ liệu, cập nhật trực tiếp DOM và bộ tính giờ.
useEffect
chấp nhận hai đối số. Đối số thứ hai là tùy chọn.
useEffect(<function>, <dependency>)
Hãy sử dụng bộ đếm thời gian làm ví dụ.
Thí dụ:
Sử dụng setTimeout()
để đếm 1 giây sau khi kết xuất ban đầu:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
});
return <h1>I've rendered {count} times!</h1>;
}
ReactDOM.render(<Timer />, document.getElementById('root'));
Nhưng chờ đã !! Tôi tiếp tục đếm mặc dù nó chỉ nên đếm một lần!
useEffect
chạy trên mọi kết xuất. Điều đó có nghĩa là khi số lượng thay đổi, kết xuất sẽ xảy ra, điều này sau đó sẽ kích hoạt một hiệu ứng khác.
Đây không phải là những gì chúng tôi muốn. Có một số cách để kiểm soát khi các tác dụng phụ chạy.
Chúng ta phải luôn bao gồm tham số thứ hai chấp nhận một mảng. Chúng ta có thể tùy ý chuyển các phụ thuộc vào useEffect
trong mảng này.
1. Không có phụ thuộc nào được thông qua:
useEffect(() => {
//Runs on every render
});
2. Một mảng trống:
useEffect(() => {
//Runs only on the first render
}, []);
3. Đạo cụ hoặc giá trị trạng thái:
useEffect(() => {
//Runs on the first render
//And any time any dependency value changes
}, [prop, state]);
Vì vậy, để khắc phục sự cố này, chúng ta hãy chỉ chạy hiệu ứng này trên kết xuất ban đầu.
Thí dụ:
Chỉ chạy hiệu ứng trên kết xuất ban đầu:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
}, []); // <- add empty brackets here
return <h1>I've rendered {count} times!</h1>;
}
ReactDOM.render(<Timer />, document.getElementById('root'));
Thí dụ:
Đây là một ví dụ về một useEffect
Hook phụ thuộc vào một biến. Nếu count
biến cập nhật, hiệu ứng sẽ chạy lại:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Counter() {
const [count, setCount] = useState(0);
const [calculation, setCalculation] = useState(0);
useEffect(() => {
setCalculation(() => count * 2);
}, [count]); // <- add the count variable here
return (
<>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>+</button>
<p>Calculation: {calculation}</p>
</>
);
}
ReactDOM.render(<Counter />, document.getElementById('root'));
Nếu có nhiều phần phụ thuộc, chúng nên được đưa vào useEffect
mảng phụ thuộc.
Được chứng nhận!
$ 95 GHI DANH
Xóa hiệu ứng
Một số hiệu ứng yêu cầu dọn dẹp để giảm rò rỉ bộ nhớ.
Hết thời gian chờ, đăng ký, trình nghe sự kiện và các hiệu ứng khác không còn cần thiết nên được xử lý.
Chúng tôi thực hiện điều này bằng cách bao gồm một hàm trả về ở cuối useEffect
Hook.
Thí dụ:
Dọn dẹp bộ đếm thời gian ở cuối useEffect
Hook:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
let timer = setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
return () => clearTimeout(timer)
}, []);
return <h1>I've rendered {count} times!</h1>;
}
ReactDOM.render(<Timer />, document.getElementById("root"));
Lưu ý: Để xóa bộ đếm thời gian, chúng tôi phải đặt tên cho nó.