我正在學習 ReactJS 和 Javascript,我遇到了這個問題,我不知道為什么會這樣,但我想我知道我的函式setEpisodeList通過一遍又一遍地設定狀態來渲染太多次我猜猜,我如何在我的代碼中解決這個問題?
該info狀態包含一個episodes具有陣列型別的物件。
我在 1 個陣列中有 1000 多個集,所以我想將episodes包含 1000 多個集的 1 個大陣列拆分為更小的塊,每個塊將是一個包含 10 個集的陣列,這就是我使用episodeListChunk.push(info.episodes.splice(0, 10)).
所以會變成
[
[chunk 1 - 10 episodes],
[chunk 2 - 10 episodes],
[chunk 3 - 10 episodes],
[chunk 4 - 10 episodes], ...
]
如果我使用console.log(episodeListChunk),我發現它作業正常。

但如果我是setEpisodeList(episodeListChunk),那么我會得到太多的重新渲染。這是否意味著每次 while 回圈運行時都會 setState ?如果是這樣,我應該采取哪種方法來處理這些情況?
這是我的代碼:
function MovieWatch({ instance }) {
const [info, setInfo] = useState([])
const [done, setDone] = useState(false)
const [episodeList, setEpisodeList] = useState([])
let { slug } = useParams()
const getInfo = async () => {
const { data } = await instance.get("/getInfo?slug=" slug)
setInfo(data.data)
setDone(true)
}
useEffect(() => {
getInfo()
}, [])
const chunkEpisode = () => {
const episodeListChunk = []
while (info.episodes.length) {
episodeListChunk.push(info.episodes.splice(0, 10))
}
setEpisodeList(episodeListChunk)
}
return (
<>
<div>Hello info page</div>
{!done ? (
<Loading loading={true} background="#000000" loaderColor="#FFFF00" />
) : (
<>
{info ? chunkEpisode() : console.log("")}
<div>Done loading</div>
</>
)}
</>
)
}
uj5u.com熱心網友回復:
您在渲染組件時設定資訊。然后您正在檢查是否設定了資訊并運行 chunkEpisodes 函式。{info ? chunkEpisode() : console.log("")}. 每次都會設定資訊,因此您不斷運行 chunkEpisodes 功能。而不是運行這個檢查,你應該把它放在一個 useEffect 掛鉤中,并將 info 作為依賴項,如果設定了 info,則運行 chunkEpisodes 函式。像這樣:
useEffect(() => {
if(info){
chunkEpisode()
}
}, [info])
uj5u.com熱心網友回復:
在 React 中,每次任何狀態發生變化時,整個組件都會重新渲染。
當這種情況發生時,React 將通過 JSX 并嘗試檢測任何狀態的更改并重新渲染它們。
因為,您已經在 J??SX 中呼叫chunkEpisode(),所以它會導致狀態更改,即episodeList. 由于狀態改變,JSX 被重新渲染,chunkEpisode()再次呼叫。這是無限發生的。
更好的方法是chunkEpisode()使用useEffect鉤子呼叫。
useEffect(() => {
if (info) {
chunkEpisode()
}
}, [info])
并洗掉這一行
{info ? chunkEpisode() : console.log("")}
uj5u.com熱心網友回復:
在獲得回應和設定資訊后,使用資料呼叫 chunkEpisode(),而不是從回傳中呼叫它。
const getInfo = async () => {
const { data } = await instance.get("/getInfo?slug=" slug)
setInfo(data.data)
chunkEpisode(data.data)
setDone(true)
}
uj5u.com熱心網友回復:
在閱讀了上面的一些答案后,我一開始嘗試不創建 1 個大陣列,然后每當我第一次收到那個大陣列時就拼接它,我不知道我的解釋是否正確。 ..
從@Rejo Mathew 的使用方式來看chunkEpisode(data.data),我想知道設定info狀態的意義何在,所以我洗掉了它,并從@Steve K 和@MWO 解釋,我嘗試這樣做。現在作業正常。
但是,我仍然不想這樣做,對我來說似乎比第一個奇怪,因為第一個對我來說似乎很酷,奇怪為什么它不起作用。
而不是setInfo, 然后使用它info來實作到函式中,我只是使用我收到的資料而不設定它,然后合并chunkEpisode到getInfo函式中,然后使用useEffectto 只在我猜到時呼叫它。
這是我完成后的代碼:
function MovieWatch({ instance }) {
const [done, setDone] = useState(false)
const [episodeList, setEpisodeList] = useState([])
let { slug } = useParams()
const getInfo = async () => {
const { data } = await instance.get("/getInfo?slug=" slug)
const episodeListChunk = []
while (data.data.episodes.length) {
episodeListChunk.push(data.data.episodes.splice(0, 10))
}
setEpisodeList(episodeListChunk)
setDone(true)
}
useEffect(() => {
getInfo()
}, [])
return (
<>
<div>Hello info page</div>
{!done ? (
<Loading loading={true} background="#000000" loaderColor="#FFFF00" />
) : (
<>
{console.log(episodeList)}
<div>Done loading</div>
</>
)}
</>
)
}
我以這種方式更改代碼后的結果。

但請給我更多建議來優化它。
uj5u.com熱心網友回復:
我猜你的問題出在info.episodes.splice(0, 10). Splice 改變資訊狀態并觸發連續的重新渲染。
如果您這樣做,您將看到錯誤消失并且episodeList狀態已更新。
所以取決于你對 slice 的意圖,你可以從這里開始并修改下面的代碼:
function MovieWatch({ instance }) {
const [info, setInfo] = useState([])
const [done, setDone] = useState(false)
const [episodeList, setEpisodeList] = useState([])
let { slug } = useParams()
const getInfo = async () => {
const { data } = await instance.get("/getInfo?slug=" slug)
setInfo(data.data)
setDone(true)
}
useEffect( () => {
getInfo();
}, [])
const chunkEpisode = () => {
const episodeListChunk = []
// while (info.episodes.length) {
// episodeListChunk.push(info.episodes.splice(0, 10))
// }
info.episodes.forEach((e)=>{
episodeListChunk.push(e)
})
console.log(episodeListChunk);
setEpisodeList(episodeListChunk)
}
return (
<>
<div>Hello info page</div>
{!done ? (
<Loading loading={true} background="#000000" loaderColor="#FFFF00" />
) : (
<>
{/* {info ? chunkEpisode() : console.log("")} */}
{episodeList.length ? episodeList : (chunkEpisode(), console.log(""))}
<div>Done loading</div>
</>
)}
</>
)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/413821.html
標籤:
