另一种重构代码的方式:
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 你的效果不依赖于任何来自 props 或 state 的值,所以它永远不需要重新运行。这不是作为特殊情况处理的——它直接遵循依赖项数组的工作方式。
如果您传递一个空数组 ([]),则效果中的 props 和 state 将始终具有它们的初始值。而将 [] 作为第二个参数传递更接近于熟悉的 componentDidMount 和 componentWillUnmount 心理模型...
我们调用setQuotes 代替setState,这用于更新引号列表,我传入了新的引号数组result.data。
所以我传入fetchQuote,然后将提供给quote组件的prop传递给它。
useEffect 中空数组的第二个参数非常强大,并且不容易立即为每个人解释和/或理解。例如,如果您在没有空数组作为第二个参数的情况下执行类似 useEffect(() => {}) 的操作,则该 useEffect 函数将不间断地向 JSON 服务器端点或其他请求发出请求。
如果您将useEffect(() => {}, []) 与空数组一起使用,它只会被调用一次,这与在基于类的组件中使用componentDidMount 相同。
在我上面给出的示例中,我正在检查以限制 useEffect 被调用的频率,我传入了 props 的值。
我没有将异步函数放在 useEffect 中的原因是因为我的理解是,如果我们传递异步函数或返回 Promise 的函数,至少根据错误,我们不能使用 useEffect我以前见过。
话虽如此,有一个解决该限制的方法,如下所示:
useEffect(
() => {
(async quote => {
const result = await axios.get(quotesURL);
setQuotes(result.data);
})(quote);
},
[quote]
);
这是一个更令人困惑的语法,但它应该有效,因为我们正在定义一个函数并立即调用它。类似于这样:
(() => console.log('howdy'))()