[英]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.