Tôi khuyên bạn nên xem câu trả lời của Dan Abramov (một trong những người duy trì cốt lõi React) ở đây :
Tôi nghĩ bạn đang làm cho nó phức tạp hơn mức cần thiết.
function Example() {
const [data, dataSet] = useState<any>(null)
useEffect(() => {
async function fetchMyAPI() {
let response = await fetch('api/data')
response = await response.json()
dataSet(response)
}
fetchMyAPI()
}, [])
return <div>{JSON.stringify(data)}</div>
}
Về lâu dài, chúng tôi sẽ không khuyến khích mô hình này vì nó khuyến khích các điều kiện chủng tộc. Chẳng hạn như - bất cứ điều gì có thể xảy ra giữa cuộc gọi của bạn bắt đầu và kết thúc, và bạn có thể nhận được các đạo cụ mới. Thay vào đó, chúng tôi sẽ khuyên bạn nên Tạm ngưng để tìm nạp dữ liệu trông giống
const response = MyAPIResource.read();
và không có hiệu ứng. Nhưng trong thời gian chờ đợi, bạn có thể di chuyển nội dung không đồng bộ sang một chức năng riêng biệt và gọi nó.
Bạn có thể đọc thêm về hồi hộp thử nghiệm tại đây .
Nếu bạn muốn sử dụng các chức năng bên ngoài với eslint.
function OutsideUsageExample() {
const [data, dataSet] = useState<any>(null)
const fetchMyAPI = useCallback(async () => {
let response = await fetch('api/data')
response = await response.json()
dataSet(response)
}, [])
useEffect(() => {
fetchMyAPI()
}, [fetchMyAPI])
return (
<div>
<div>data: {JSON.stringify(data)}</div>
<div>
<button onClick={fetchMyAPI}>manual fetch</button>
</div>
</div>
)
}
Với useCallback useCallback . Hộp cát .
import React, { useState, useEffect, useCallback } from "react";
export default function App() {
const [counter, setCounter] = useState(1);
// if counter is changed, than fn will be updated with new counter value
const fn = useCallback(() => {
setCounter(counter + 1);
}, [counter]);
// if counter is changed, than fn will not be updated and counter will be always 1 inside fn
/*const fnBad = useCallback(() => {
setCounter(counter + 1);
}, []);*/
// if fn or counter is changed, than useEffect will rerun
useEffect(() => {
if (!(counter % 2)) return; // this will stop the loop if counter is not even
fn();
}, [fn, counter]);
// this will be infinite loop because fn is always changing with new counter value
/*useEffect(() => {
fn();
}, [fn]);*/
return (
<div>
<div>Counter is {counter}</div>
<button onClick={fn}>add +1 count</button>
</div>
);
}
useEffect(() => { let unmounted = false promise.then(res => { if (!unmounted) { setState(...) } }) return () => { unmounted = true } }, [])