score:1

Accepted answer

i'm not sure if your current code works as you're expecting it to. here:

classname={
  (this.state.selections[lang][cat][sect][letter].correct ? correct : unanswered),
  (this.state.selections[lang][cat][sect][letter].incorrect ? incorrect : unanswered)
}

you're invoking the comma operator, which evaluates to only the final expression in the comma-separated list. it's equivalent to:

classname={
  (this.state.selections[lang][cat][sect][letter].incorrect ? incorrect : unanswered)
}

to fix it, either use a nested conditional operator, or pass it into a function.

to make your code more concise, instead of iterating over the keys of the object, iterate over the values of the object. you also don't need a fragment <></> when returning an array.

<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>

to avoid the nested conditional, if that's your preference, do something like:

<div
    classname={getclass(letter)}
    key={index}
></div>
const getclass = (letter) => {
  if (letter.correct) return correct;
  if (letter.incorrect) return incorrect;
  return unanswered;
};

you could also consider changing your model so that the question state (correct/incorrect/unanswered) is a single property, rather than multiple, eg, instead of

"correct": false,
"incorrect": false,
"unanswered": true

have

answerstate: 2

where 2 corresponds to unanswered, 1 corresponds to incorrect, and 0 corresponds to correct - or something like that. then you can use an array to look up the appropriate class name:

classname={classnames[letter.answerstate]}
const classnames = [correct, incorrect, unanswered];

Related Query

More Query from same tag