[英]JSX Conditional Rendering for Nested Object Values
我試圖讓“抽認卡”在未回答時不顯示背景顏色,正確回答時顯示綠色,錯誤回答時顯示黃色。 每張卡片的屬性都存儲在一個嵌套對象中。 我在使用條件渲染來正確顯示我的內容時遇到問題。
代碼:這里是我想要完成的,但是JSX條件語句只是在className中注冊了最后一個語句。
<div className="row">
{Object.keys(this.state.selections).map( (lang, index) => (
<>
{Object.keys(this.state.selections[lang]).map( (cat, index) => (
<>
{Object.keys(this.state.selections[lang][cat]).map( (sect, index)=> (
<>
{Object.keys(this.state.selections[lang][cat][sect]).map( (letter, index)=> (
<>
{this.state.selections[lang][cat][sect][letter].show &&
<div className={
(this.state.selections[lang][cat][sect][letter].correct ? correct: unanswered),
(this.state.selections[lang][cat][sect][letter].incorrect ? incorrect : unanswered)
} key= {index}>
</div>
}
</>
))}
</>
))}
</>
))}
</>
))}
</div>
本質上,我想在 className 中放置一個條件語句,以根據對象屬性值為 true/false 來更改背景。
對象模型:
{
"Hiragana": {
"Main Kana": {
"Vowels": {
"a": {
"characterName": "A",
"character": "あ",
"unicode": "\u0026#12354;",
"hexEncoding": "\u0026#x3042",
"englishTranslation": "a",
"alternateEnglishTranslation": "",
"isLetter": "1",
"alphabet": "hir",
"show": false,
"answer": "",
"correct": false,
"incorrect": false,
"unanswered": true
},
額外問題:必須遍歷每個對象層似乎有點混亂和乏味......有什么好方法可以縮短它嗎? lang和cat是通過輸入選擇的,因此它們不能被硬編碼。 雖然我目前的解決方案“有效”,但我想盡可能提高自己。
更新: @CertainPerformance 提供的解決方案中的工作代碼
<div className="row">
{Object.keys(this.state.selections).map(lang =>
Object.values(this.state.selections).map( (cat) =>
Object.values(cat).map((sect, indexCat) =>
Object.values(sect).map((sectLetters, indexSect) =>
Object.values(sectLetters).map((letter, indexSectL) =>
letter.show &&
<div
className={getBgClass(letter)}
key={indexSectL}>
<div>
<h5 className="card-title" >{letter.character}</h5>
<input data-lang={lang} data-cat={Object.getOwnPropertyNames(cat)[indexCat]} data-sect={Object.getOwnPropertyNames(sect)[indexSect]} type="text" name={letter.characterName} value={letter.answer} onChange={this.handleChange.bind(this)} />
</div>
</div>
)
)
)
)
)}
</div>
對於那些對我訪問 Object.values 生成的數組的解釋感到困惑的人,這里有一個帶有簡單 console.log 的示例以更好地解釋。
Object.values(this.state.selections).map((cat) =>{
Object.values(cat).map((sect, indexCat) => {
console.log("Cat: ", Object.getOwnPropertyNames(cat)[indexCat]);
});
});
我不確定您當前的代碼是否像您期望的那樣工作。 這里:
className={
(this.state.selections[lang][cat][sect][letter].correct ? correct : unanswered),
(this.state.selections[lang][cat][sect][letter].incorrect ? incorrect : unanswered)
}
您正在調用逗號運算符,它僅計算逗號分隔列表中的最終表達式。 它相當於:
className={
(this.state.selections[lang][cat][sect][letter].incorrect ? incorrect : unanswered)
}
要修復它,請使用嵌套條件運算符,或將其傳遞給函數。
為了使您的代碼更簡潔,而不是迭代對象的鍵,而是迭代對象的值。 返回數組時也不需要片段<></>
。
<div className="row">
{Object.values(this.state.selections).map(selection =>
Object.values(selection).map(cat =>
Object.values(cat).map(sect =>
Object.values(sect).map((letter, index) =>
letter.show &&
<div
className={
letter.correct
? correct
: letter.incorrect
? incorrect
:
unanswered
}
key={index}
>
</div>
)
)
)
)}
</div>
為了避免嵌套條件,如果這是您的偏好,請執行以下操作:
<div
className={getClass(letter)}
key={index}
></div>
const getClass = (letter) => {
if (letter.correct) return correct;
if (letter.incorrect) return incorrect;
return unanswered;
};
您還可以考慮更改您的模型,以便問題狀態(正確/不正確/未回答)是單個屬性,而不是多個屬性,例如,而不是
"correct": false,
"incorrect": false,
"unanswered": true
有
answerState: 2
其中 2 對應於未回答,1 對應於不正確,0 對應於正確 - 或類似的東西。 然后你可以使用一個數組來查找合適的類名:
className={classNames[letter.answerState]}
const classNames = [correct, incorrect, unanswered];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.