Где я могу сделать вызов API с хуками в реакции?
В основном мы выполняем вызовы API в методе жизненного цикла componentDidMount()
в компонентах класса React, как показано ниже
componentDidMount(){
//Here we do API call and do setState accordingly
}
Но после того, как в React v16.7.0 введены хуки, все они в основном похожи на функциональные компоненты
Мой вопрос: где именно нам нужно сделать вызов API в функциональном компоненте с перехватчиками?
У нас есть какой-нибудь метод для этого, подобный componentDidMount()
?
Ответы
Ответ 1
Да, есть аналогичный (но не тот же самый!) Заменитель componentDidMount
с хуками, и это хук useEffect
.
Другие ответы на самом деле не отвечают на ваш вопрос о том, где вы можете делать вызовы API. Вы можете выполнять вызовы API, используя useEffect
и передавая пустой массив или объект в качестве второго аргумента в качестве замены componentDidMount()
. Ключ здесь - второй аргумент. Если вы не предоставите пустой массив или объект в качестве второго аргумента, вызов API будет вызываться при каждом рендеринге, и он фактически становится componentDidUpdate
.
Как упомянуто в документах:
Передача пустого массива [] входных данных говорит React, что ваш эффект не зависит от каких-либо значений из компонента, так что эффект будет работать только при монтировании и очистке при размонтировании; это не будет работать на обновлениях.
Вот несколько примеров сценариев, в которых вам нужно будет выполнять вызовы API:
Вызов API строго на горе
Попробуйте запустить приведенный ниже код и посмотрите результат.
function User() {
const [firstName, setFirstName] = React.useState(null);
const [lastName, setLastName] = React.useState(null);
React.useEffect(() => {
fetch('https://randomuser.me/api/')
.then(results => results.json())
.then(data => {
const {name} = data.results[0];
setFirstName(name.first);
setLastName(name.last);
});
}, []); // <-- Have to pass in [] here!
return (
<div>
Name: {!firstName || !lastName ? 'Loading...' : '${firstName} ${lastName}'}
</div>
);
}
ReactDOM.render(<User />, document.querySelector('#app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>
Ответ 2
Вы можете использовать библиотеку, которая предоставляет вам хуки, например https://resthooks.io
Тогда получение ваших данных становится простым:
const article = useResource(ArticleResource.detailShape(), { id });
Теперь вы захватили статью по id. Все несоответствующие пути (загрузка, состояния ошибок) обрабатываются границами Suspense и Error соответственно.
Для начала следуйте этому простому руководству: https://resthooks.io/docs/getting-started/installation
При сжатии всего 7 Кбайт это избавит вас от многих проблем и в конечном итоге уменьшит размер вашего пакета из-за меньшего количества повторяющегося кода.
Ответ 3
Когда вы используете функциональные компоненты с API-интерфейсом ловушек, вы можете использовать метод useEffect()
для создания побочных эффектов. Всякий раз, когда состояние обновляется из-за этих побочных эффектов, компонент будет повторно отображаться.
Пример из документов.
import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = 'You clicked ${count} times';
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Например, вы можете вызвать setCount
в функции обратного вызова асинхронного запроса. Когда обратный вызов будет выполнен, состояние будет обновлено, и React выполнит повторную визуализацию компонента. Также из документов:
Совет
Если вы знакомы с методами жизненного цикла класса React, вы можете использовать useEffect Hook как комбинацию componentDidMount
, componentDidUpdate
и componentWillUnmount
.
Ответ 4
Вы также можете использовать use-http
как:
import useFetch from 'use-http'
function App() {
// add whatever other options you would add to 'fetch' such as headers
const options = {
method: 'POST',
body: {}, // whatever data you want to send
}
var [data, loading, error] = useFetch('https://example.com', options)
// want to use object destructuring? You can do that too
var { data, loading, error } = useFetch('https://example.com', options)
if (error) {
return 'Error!'
}
if (loading) {
return 'Loading!'
}
return (
<code>
<pre>{data}</pre>
</code>
)
}