为什么在第一个代码中,当调用 setAllMemes 时,组件会在重新渲染之前等待所有代码完成,而在第二个代码中,它会在代码完成之前重新渲染
import React from "react"
export default function Meme() {
console.log("react render")
const [allMemes, setAllMemes] = React.useState([])
console.log("allMemes outside the use effect" , allMemes)
React.useEffect(() => {
console.log("before setAllMemes")
setAllMemes(["string1","string2"]);
console.log("after setAllMemes");
console.log("allMemes inside the use effect" , allMemes);
}, [])
return (
<main>
</main>
)
}
›react render
›allMemes outside the use effect,[]
›before setAllMemes
›after setAllMemes
›allMemes inside the use effect,[]
›react render
›allMemes outside the use effect,["string1", "string2"]
import React from "react"
export default function Meme() {
console.log("react render")
const [allMemes, setAllMemes] = React.useState([])
console.log("allMemes outside the use effect" , allMemes)
React.useEffect(() => {
fetch("https://api.imgflip.com/get_memes")
.then(res => res.json())
.then(data => {
console.log("before setAllMemes")
setAllMemes(data.data.memes);
console.log("after setAllMemes");
})
console.log("allMemes inside the use effect" , allMemes);
}, [])
return (
<main>
</main>
)
}
›react render
›allMemes outside the use effect,[]
›allMemes inside the use effect,[]
›before setAllMemes
›react render
›allMemes outside the use effect [array of object from the api]
›after setAllMemes
在第一个代码片段中,setAllMemes 函数在 useEffect 挂钩内同步调用。由于这是同步的,因此它会在执行下一行代码之前完成。当您在 useEffect 中记录 allMemes 时,它仍然显示一个空数组,因为状态更新尚未生效。当组件在状态更新后重新渲染时,会显示更新后的 allMemes 数组。
在第二个代码片段中,从 api 获取数据后,在 useEffect 挂钩内异步调用 setAllMemes 函数。 fetch 返回一个 Promise,并且在 Promise 的 then 回调中调用 setAllMemes 函数。这意味着setAllMemes是异步调用的,在获取数据的过程中,获取操作之后的下一行代码将继续执行。当您在 useEffect 中记录 allMemes 时,它仍然显示一个空数组,因为状态更新尚未发生。
您的输出出现问题。通过运行此代码片段进行检查。
after setAllMemes
之前不渲染。
function Meme() {
console.log("react render")
const [allMemes, setAllMemes] = React.useState([])
console.log("allMemes outside the use effect" , allMemes)
React.useEffect(() => {
fetch("https://api.imgflip.com/get_memes")
.then(res => res.json())
.then(data => {
console.log("before setAllMemes")
setAllMemes(data.data.memes);
console.log("after setAllMemes");
})
console.log("allMemes inside the use effect" , allMemes);
}, [])
return (
<main>
</main>
)
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Meme />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>