Javascript 嵌套对象值的JSX条件呈现
我试图让一张“抽认卡”在未回答时不显示背景色,回答正确时显示绿色,回答错误时显示黄色。每张卡的属性存储在嵌套对象中。我在使用条件呈现来正确显示我的内容时遇到问题 代码:这里是我想要完成的,但是JSX条件语句只注册类名中的最后一条语句Javascript 嵌套对象值的JSX条件呈现,javascript,reactjs,object,jsx,Javascript,Reactjs,Object,Jsx,我试图让一张“抽认卡”在未回答时不显示背景色,回答正确时显示绿色,回答错误时显示黄色。每张卡的属性存储在嵌套对象中。我在使用条件呈现来正确显示我的内容时遇到问题 代码:这里是我想要完成的,但是JSX条件语句只注册类名中的最后一条语句 <div className="row"> {Object.keys(this.state.selections).map( (lang, index) => ( <>
<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>
附加问题:必须循环遍历每个对象层似乎有点混乱和乏味。。。有什么好办法可以缩短这个时间吗?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>
我不确定您当前的代码是否按照预期工作。在这里:
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>
你也可以考虑改变你的模型,使问题状态(正确的/不正确的/未回答的)是一个单一的属性,而不是多个属性,例如,而不是
"correct": false,
"incorrect": false,
"unanswered": true
有
其中2对应未回答,1对应不正确,0对应正确-或类似的东西。然后可以使用数组查找相应的类名:
className={classNames[letter.answerState]}
你是一个受祝福的人。这是我需要的一切,还有更多。我想我现在要保留这三个属性,以便更好地可视化它。另外,了解如何钻取Object.values也是非常有趣的。。。似乎为了访问它生成的数组,您必须下一个.map函数,并使用嵌套的索引在父数组中循环。。。非常奇怪,很难解释,但我会用最终结果更新我的问题!
<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
className={classNames[letter.answerState]}
const classNames = [correct, incorrect, unanswered];