在useEffect及点击事件中调用loadData提示‘函数未定义’问题
问题原因
loadData函数被定义在useEffect的回调内部,属于局部作用域,组件返回的JSX里的按钮onClick无法访问到该函数,因此抛出"loadData is not defined"错误。
解决方案
方案一:将loadData提升到组件作用域
把loadData定义在useEffect外部,让整个组件都能访问,同时在useEffect中调用它完成初始化:
function App() { // 初始值用空字符串更匹配笑话的文本类型 const [joke, setJoke] = useState(''); const API_LINK = "https://icanhazdadjoke.com/"; // 定义在组件作用域,全局可访问 const loadData = async () => { const response = await axios.get(`${API_LINK}`, { headers: { Accept: "application/json" } }); console.log(response.data.joke); setJoke(response.data.joke); }; useEffect(() => { loadData(); // 初始化调用 }, []); return ( <div className="container"> <h2 className="title">The Absolute Best Dad jokes.</h2> <div className="joke">{joke}</div> <button className="btn btn-primary" onClick={loadData}> Get Another Joke </button> </div> ); } export default App;
如果想优化性能,避免loadData每次渲染都重新创建,可以用useCallback包裹:
import { useState, useEffect, useCallback } from 'react'; function App() { const [joke, setJoke] = useState(''); const API_LINK = "https://icanhazdadjoke.com/"; const loadData = useCallback(async () => { const response = await axios.get(`${API_LINK}`, { headers: { Accept: "application/json" } }); setJoke(response.data.joke); }, [API_LINK]); useEffect(() => { loadData(); }, [loadData]); return ( <div className="container"> <h2 className="title">The Absolute Best Dad jokes.</h2> <div className="joke">{joke}</div> <button className="btn btn-primary" onClick={loadData}> Get Another Joke </button> </div> ); } export default App;
方案二:直接在onClick中编写逻辑
如果不想单独提取函数,也可以直接在按钮的onClick里写入异步逻辑:
function App() { const [joke, setJoke] = useState(''); const API_LINK = "https://icanhazdadjoke.com/"; useEffect(() => { const loadData = async () => { const response = await axios.get(`${API_LINK}`, { headers: { Accept: "application/json" } }); setJoke(response.data.joke); }; loadData(); }, []); return ( <div className="container"> <h2 className="title">The Absolute Best Dad jokes.</h2> <div className="joke">{joke}</div> <button className="btn btn-primary" onClick={async () => { const response = await axios.get(`${API_LINK}`, { headers: { Accept: "application/json" } }); setJoke(response.data.joke); }}> Get Another Joke </button> </div> ); } export default App;
内容的提问来源于stack exchange,提问作者Michael Yount
相关产品推荐
相关产品推荐

