A case for ternaries in JSX
Kent C. Dodds has a great article on why you should “Use ternaries rather than && in JSX.” I paste a link to it whenever I see condition && render
instead of ternaries in a PR review. But I sometimes get a quite valid response, saying that it isn’t a problem in the specific situation in the PR. condition && render
is only really a problem when condition
could be a number. For example:
function Something() { const isValid = false; const name = ""; const users = []; return ( <> <div>Boolean: {isValid && "has boolean value"}</div> <div>String: {name && "has name value"}</div> <div>Number: {users.length && "has number value"}</div> ) }
In this example, no message will be displayed for “Boolean” and “String”. However, “Number” will show a message of 0
(see Kent’s article to find out why this happens).
So why can’t we use condition && render
for booleans, strings, and any other truthy value, and just avoid it for numbers? That reasonable. It avoids the real issue. However, there’s another problem with this approach: when you’re doing a PR review, you have to pay close attention to every condition && render
in the PR and figure out whether it will create the bug Kent describes.
The response I’m proposing in this article is that the cognitive load required to mentally parse all condition && render
conditions in order to find out if they will accidentally render a 0
is a waste of time. It’s easier to just never allow them and use ternaries instead. You’ll never hit this bug, you’ll avoid annoying debates in your PR reviews, and you won’t need to figure out if a condition could reduce to 0
.
What to do?
If you decide to get rid of &&
rendering, how would you enforce that decision on a project? You could leave a link to this article whenever you see a condition && render
in PR review, but that’s not fun and it creates an opportunity to rehash the decision.
Thankfully there’s a lint rule for this called react/jsx-no-leaked-render. Just install the eslint-plugin-react plugin and add this to your ESLint config:
{ "react/jsx-no-leaked-render": ["error", { "validStrategies": ["ternary"] }] }
There’s also a coerce
strategy that forces you to coerce the condition
to a boolean for it to be valid (or you can allow coerce
and ternary
, which is the default).
Whatever strategy you choose to support, this will guarantee your project will be free of risky condition && render
statements and you’ll never need to have the &&
vs. ternary conversation in your PR reviews ever again.
Note that, at the time of writing this article, the react/jsx-no-leaked-render
rule is a little overeager in finding &&
conditions in JSX. It will call out &&
when setting props, not just when used for rendering. See this issue for details: https://github.com/jsx-eslint/eslint-plugin-react/issues/3292