Еще один способ реструктурировать ваш код для работы:
const quotesURL = "https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json";
function QuoteGenerator = ({ quote }) => {
const [quotes, setQuotes] = useState([]);
const [currentQuote, setCurrentQuote] = useState({ quote: "", author: "" });
const fetchQuote = async quote => {
const result = await axios.get(quotesURL);
setQuotes(result.data);
};
useEffect(() => {
fetchQuote(quote);
}, [quote]);
};
Так что теперь у вас есть функция внутри вашего QuoteGenerator
функционального компонента, которая называется fetchQuote
. Хук useEffect
позволяет нам использовать что-то вроде методов жизненного цикла, вроде сочетания методов жизненного цикла componentDidMount
и componentDidUpdate
. В этом случае я вызывал useEffect
с функцией, запускаемой каждый раз, когда этот компонент первоначально отображается на экране, а также каждый раз, когда компонент обновляется.
В других ответах вы видите, что второй аргумент передается как пустой массив. Я поместил quote
в качестве первого элемента внутри этого пустого массива, поскольку он был передан в качестве опоры в моем примере, но в примере других это не так, поэтому у них есть пустой массив.
Если вы хотите понять, почему мы используем пустой массив в качестве второго аргумента, я думаю, что лучший способ объяснить это - процитировать Hooks API:
Если вы хотите запустить эффект и очистить его только один раз (при монтировании и демонтировании), вы можете передать пустой массив ([]) в качестве второго аргумента. Это говорит React, что ваш эффект не зависит от каких-либо значений из реквизита или состояния, поэтому его не нужно повторно запускать. Это не обрабатывается как особый случай - это следует непосредственно из того, как всегда работает массив зависимостей.
Если вы передадите пустой массив ([]), реквизиты и состояние как внутри эффекта всегда будут иметь свои начальные значения. При передаче [] в качестве второго аргумента ближе к знакомой ментальной модели componentDidMount и componentWillUnmount ...
Вместо setState
мы вызываем setQuotes
, и это используется для обновления списка цитат, и я передал новый массив цитат, который result.data
.
Итак, я передал fetchQuote
, а затем передал ему реквизит, предоставленный компоненту quote
.
Второй аргумент пустого массива в useEffect
довольно мощный, и его нелегко объяснить и / или понять всем сразу. Например, если вы сделаете что-то вроде этого useEffect(() => {})
без пустого массива в качестве второго аргумента, эта функция useEffect
будет выполнять безостановочные запросы к конечной точке сервера json или что-либо еще.
Если вы используете useEffect(() => {}, [])
с пустым массивом, он будет вызван только один раз, что идентично использованию componentDidMount
в компоненте на основе классов.
В приведенном выше примере я устанавливаю проверку, чтобы ограничить частоту вызова useEffect
, и я передал значение реквизита.
Причина, по которой я не поместил асинхронную функцию в useEffect
, заключается в том, что, насколько я понимаю, мы не можем использовать useEffect
, если передаем асинхронную функцию или функцию, которая возвращает Promise, по крайней мере, в соответствии с ошибками Я видел в прошлом.
С учетом вышесказанного, существует ограничение для этого ограничения, например:
useEffect(
() => {
(async quote => {
const result = await axios.get(quotesURL);
setQuotes(result.data);
})(quote);
},
[quote]
);
Это более запутанный синтаксис, но он предположительно работает, потому что мы определяем функцию и немедленно ее вызываем. Похоже на что-то вроде этого:
(() => console.log('howdy'))()