[英]React Hooks: useState with onClick only updating the SECOND time button is clicked?
編輯:忘記了一個重要的部分 - 如果您單擊 Jeff A. Menges 旁邊的按鈕並檢查控制台日志,這會很明顯。
代碼的重要部分是按鈕代碼的onClick中的“setFullResults(cardResults.data.concat(cardResultsPageTwo.data))”行。 我認為它應該將 fullResults 設置為我告訴它的任何內容......除非它在你第一次點擊它時不起作用。 每次之后,它都有效,但不是第一次。 這對下一組來說會很麻煩,因為我無法映射未定義的數組,而且我不想告訴用戶只需單擊按鈕兩次即可出現實際搜索結果。
我猜 useEffect 會起作用,但我不知道如何編寫它或將它放在哪里。 它顯然不能在 App 功能組件的頂部工作,但是我嘗試將它放在其他任何地方都會給我一個錯誤。
我已經嘗試過“this.forceUpdate()”,很多地方都推薦它作為快速修復(但建議不要使用——但我已經嘗試了幾個小時來解決這個問題),但是“this.forceUpdate()”不是無論我把它放在哪里,都不是一個函數。
請幫助我讓這個按鈕在第一次被點擊時起作用。
import React, { useState, useEffect } from "react";
const App = () => {
let artistData = require("./mass-artists.json");
const [showTheCards, setShowTheCards] = useState();
const [fullResults, setFullResults] = useState([]);
useEffect(() => {
setFullResults();
}, []);
let artistDataMap = artistData.map(artistName => {
//console.log(artistName);
return (
<aside className="artist-section">
<span>{artistName}</span>
<button
className="astbutton"
onClick={ function GetCardList() {
fetch(
`https://api.scryfall.com/cards/search?unique=prints&q=a:"${artistName}"`
)
.then(response => {
return response.json();
})
.then((cardResults) => {
console.log(cardResults.has_more)
if (cardResults.has_more === true) {
fetch (`https://api.scryfall.com/cards/search?unique=prints&q=a:"${artistName}"&page=2`)
.then((responsepagetwo) => {
return responsepagetwo.json();
})
.then(cardResultsPageTwo => {
console.log(`First Results Page: ${cardResults}`)
console.log(`Second Results Page: ${cardResultsPageTwo}`)
setFullResults(cardResults.data.concat(cardResultsPageTwo.data))
console.log(`Full Results: ${fullResults}`)
})
}
setShowTheCards(
cardResults.data
.filter(({ digital }) => digital === false)
.map(cardData => {
if (cardData.layout === "transform") {
return (
//TODO : Transform card code
<span>Transform Card (Needs special return)</span>
)
}
else if (cardData.layout === "double_faced_token") {
return (
//TODO: Double Faced Token card code
<span>Double Faced Token (Needs special return)</span>
)
}
else {
return (
<div className="card-object">
<span className="card-object-name">
{cardData.name}
</span>
<span className="card-object-set">
{cardData.set_name}
</span>
<img
className="card-object-img-sm"
alt={cardData.name}
src={cardData.image_uris.small}
/>
</div>
)
}
})
)
});
}}
>
Show Cards
</button>
</aside>
);
});
return (
<aside>
<aside className="artist-group">
{artistDataMap}
</aside>
<aside className="card-wrapper">
{showTheCards}
</aside>
</aside>
);
};
export default App;
CodesAndBox: https ://codesandbox.io/embed/compassionate-satoshi-iq3nc ? fontsize =14
您可以嘗試重構代碼,例如 onClick 處理程序具有合成事件。 將此事件偵聽器添加為類的一部分。 使用箭頭函數,這樣你就不需要在構造函數中綁定這個函數處理程序。 獲取數據后,嘗試將狀態設置為結果,並使用該狀態在 render 方法中呈現 HTML 標記。 當我運行此代碼時,我還在控制台中看到了一個錯誤,即子元素需要 key 屬性。 我已經看到您在渲染方法中使用 Array.prototype.map,但是當您返回內部的 span 元素時,嘗試添加一個關鍵屬性,以便當 React diffing 算法遇到新元素時,它會降低檢查某些節點的時間復雜度這個關鍵屬性。
useEffect(() => {
// call the functions which depend on fullResults here
setFullResults();
}, [fullResults])
//現在它會檢查是否fullResults改變,如果改變不是內部useEffect通話功能這是根據fullResults
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.