如何在 React 的 UseEffect() 中调用异步函数?
How to call an async function inside a UseEffect() in React?
我想调用一个异步函数并为我的 UseEffect 获取结果。
我在网上找到的fetch api例子都是直接在useEffect函数中做的。
如果我的 URL 发生变化,我必须修补我的所有抓取。
当我尝试时,我收到一条错误消息。
这是我的代码。
async function getData(userId) {
const data = await axios.get(`http://url/api/data/${userId}`)
.then(promise => {
return promise.data;
})
.catch(e => {
console.error(e);
})
return data;
}
function blabla() {
const [data, setData] = useState(null);
useEffect(async () => {
setData(getData(1))
}, []);
return (
<div>
this is the {data["name"]}
</div>
);
}
index.js:1375 警告:效果函数不能 return 除了用于清理的函数之外的任何东西。
看起来你写了 useEffect(async () => ...) 或 returned 一个 Promise。相反,在你的效果中编写异步函数并立即调用它:
useEffect(() => {
async function fetchData() {
// You can await here
const response = await MyAPI.getData(someId);
// ...
}
fetchData();
}, [someId]); // Or [] if effect doesn't need props or state
最好按照警告的建议进行操作 - 在效果中调用异步函数。
function blabla() {
const [data, setData] = useState(null);
useEffect(() => {
axios.get(`http://url/api/data/1`)
.then(result => {
setData(result.data);
})
.catch(console.error)
}, []);
return (
<div>
this is the {data["name"]}
</div>
);
}
如果想将api功能保留在组件之外,也可以这样做:
async function getData(userId) {
const data = await axios.get(`http://url/api/data/${userId}`)
.then(promise => {
return promise.data;
})
.catch(e => {
console.error(e);
})
return data;
}
function blabla() {
const [data, setData] = useState(null);
useEffect(() => {
(async () => {
const newData = await getData(1);
setData(newData);
})();
}, []);
return (
<div>
this is the {data["name"]}
</div>
);
}
在你的效果中创建一个等待 getData(1)
结果然后调用 setData()
:
的异步函数
useEffect(() => {
const fetchData = async () => {
const data = await getData(1);
setData(data);
}
fetchData();
}, []);
如果您正在调用它 right-away 您可能希望将其用作匿名函数:
useEffect(() => {
(async () => {
const data = await getData(1);
setData(data);
})();
}, []);
您仍然可以在钩子外部定义异步函数并在钩子内部调用它。
const fetchData = async () => {
const data = await getData(1);
setData(data);
}
useEffect(() => {
fetchData();
}, []);
因为 getData
returns 你可以使用 Promise .then
useEffect(() => {
getData(1).then(setData);
}, []);
组件可能会在等待解决之前使用不同的 someId
卸载或重新呈现:
const unmountedRef = useRef(false);
useEffect(()=>()=>(unmountedRef.current = true), []);
useEffect(() => {
const effectStale = false; // Don't forget ; on the line before self-invoking functions
(async function() {
// You can await here
const response = await MyAPI.getData(someId);
/* Component has been unmounted. Stop to avoid
"Warning: Can't perform a React state update on an unmounted component." */
if(unmountedRef.current) return;
/* Component has re-rendered with different someId value
Stop to avoid updating state with stale response */
if(effectStale) return;
// ... update component state
})();
return ()=>(effectStale = true);
}, [someId]);
考虑使用 Suspense 加载组件之前需要加载的数据。
我想调用一个异步函数并为我的 UseEffect 获取结果。
我在网上找到的fetch api例子都是直接在useEffect函数中做的。 如果我的 URL 发生变化,我必须修补我的所有抓取。
当我尝试时,我收到一条错误消息。
这是我的代码。
async function getData(userId) {
const data = await axios.get(`http://url/api/data/${userId}`)
.then(promise => {
return promise.data;
})
.catch(e => {
console.error(e);
})
return data;
}
function blabla() {
const [data, setData] = useState(null);
useEffect(async () => {
setData(getData(1))
}, []);
return (
<div>
this is the {data["name"]}
</div>
);
}
index.js:1375 警告:效果函数不能 return 除了用于清理的函数之外的任何东西。 看起来你写了 useEffect(async () => ...) 或 returned 一个 Promise。相反,在你的效果中编写异步函数并立即调用它:
useEffect(() => {
async function fetchData() {
// You can await here
const response = await MyAPI.getData(someId);
// ...
}
fetchData();
}, [someId]); // Or [] if effect doesn't need props or state
最好按照警告的建议进行操作 - 在效果中调用异步函数。
function blabla() {
const [data, setData] = useState(null);
useEffect(() => {
axios.get(`http://url/api/data/1`)
.then(result => {
setData(result.data);
})
.catch(console.error)
}, []);
return (
<div>
this is the {data["name"]}
</div>
);
}
如果想将api功能保留在组件之外,也可以这样做:
async function getData(userId) {
const data = await axios.get(`http://url/api/data/${userId}`)
.then(promise => {
return promise.data;
})
.catch(e => {
console.error(e);
})
return data;
}
function blabla() {
const [data, setData] = useState(null);
useEffect(() => {
(async () => {
const newData = await getData(1);
setData(newData);
})();
}, []);
return (
<div>
this is the {data["name"]}
</div>
);
}
在你的效果中创建一个等待 getData(1)
结果然后调用 setData()
:
useEffect(() => {
const fetchData = async () => {
const data = await getData(1);
setData(data);
}
fetchData();
}, []);
如果您正在调用它 right-away 您可能希望将其用作匿名函数:
useEffect(() => {
(async () => {
const data = await getData(1);
setData(data);
})();
}, []);
您仍然可以在钩子外部定义异步函数并在钩子内部调用它。
const fetchData = async () => {
const data = await getData(1);
setData(data);
}
useEffect(() => {
fetchData();
}, []);
因为 getData
returns 你可以使用 Promise .then
useEffect(() => {
getData(1).then(setData);
}, []);
组件可能会在等待解决之前使用不同的 someId
卸载或重新呈现:
const unmountedRef = useRef(false);
useEffect(()=>()=>(unmountedRef.current = true), []);
useEffect(() => {
const effectStale = false; // Don't forget ; on the line before self-invoking functions
(async function() {
// You can await here
const response = await MyAPI.getData(someId);
/* Component has been unmounted. Stop to avoid
"Warning: Can't perform a React state update on an unmounted component." */
if(unmountedRef.current) return;
/* Component has re-rendered with different someId value
Stop to avoid updating state with stale response */
if(effectStale) return;
// ... update component state
})();
return ()=>(effectStale = true);
}, [someId]);
考虑使用 Suspense 加载组件之前需要加载的数据。