Дело в том, что useEffect выполняется не при каждом рендеринге.
Чтобы увидеть это более четко, давайте предположим, что ваш компонент MyComponent
визуализируется родительским компонентом (давайте назовите его ParentComponent
) и он получит реквизит от этого родительского компонента, который может измениться от действия пользователя.
ParentComponent
const ParentComponent = () => {
const [ counter, setCounter ] = useState(0);
const onButtonClicked = () => setCounter(counter + 1);
return (
<>
<button onClick={onButtonClicked}>Click me!</button>
<MyComponent counter={counter} />
</>
);
}
И ваш MyComponent
(слегка изменено для чтения и использования counter
prop):
const MyComponent = ({ counter }) => {
[data, setData] = useState();
useEffect(() => {
fetchDataFromAPI().then(res => setData(res))
}, []);
return(
<div>
<div>{counter}</div>
{data ? <div>{data}</div> : <div>Loading...</div>}
</div>
)
}
Теперь, когда компонент MyComponent
монтируется в первый раз, будет выполняться операция выборки. Если впоследствии пользователь нажимает кнопку и счетчик увеличивается, useEffect не будет выполняться (но будет вызвана функция MyComponent
для обновления из-за изменения counter
)!
Если вы не используете useEffect , когда пользователь нажимает на кнопку, операция выборки будет выполнена снова, поскольку изменилась подпорка счетчика, а метод рендеринга MyComponent
казнены.