Два варианта useEffect для загрузки данных. Какой правильный и почему?
middle
correct_vs_wrong
#320
Вариант 1
function UserProfile({ userId }: { userId: number }) {
const [data, setData] = useState<User | null>(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(r => r.json())
.then(setData);
}, []); // ❌ deps пустые — не реагирует на смену userId
return <div>{data?.name}</div>;
}
Вариант 2
function UserProfile({ userId }: { userId: number }) {
const [data, setData] = useState<User | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const ctrl = new AbortController();
setLoading(true);
setError(null);
fetch(`/api/users/${userId}`, { signal: ctrl.signal })
.then(r => r.ok ? r.json() : Promise.reject(new Error(r.statusText)))
.then(setData)
.catch(e => { if (e.name !== 'AbortError') setError(String(e)); })
.finally(() => setLoading(false));
return () => ctrl.abort(); // cleanup → отменяем при смене userId / unmount
}, [userId]); // ✅ зависим от userId
if (loading) return <Spinner/>;
if (error) return <Err msg={error}/>;
return <div>{data?.name}</div>;
}
Чтобы решить вопрос и сохранить попытку — войди.