---
title: "ADR: Use of conditionals in JSX (deprecation of ``)"
---
## Background
Using the `&&` operator in React can lead to unexpected rendering behavior when dealing with certain falsy values. In our codebase, the `` component has been used to render React elements based on a boolean condition. However, it has certain drawbacks, which is why we would like to replace it with the ternary operator.
### Pitfalls of `&&` operator
While most truthy and falsy values behave as expected with the `&&` operator, certain falsy values can produce unintended outcomes:
```tsx
{NaN && 
❔
} // will render `NaN`
{0 && ❔
} // will render `0`
{arr?.length && ❔
} // can render `0`
```
These issues can cause bugs in components that conditionally render UI elements based on numeric values or other potentially falsy conditions. For this reason, we use a wrapper.
```tsx
❔}
/>
```
### What's wrong with ``
While this solves leaking render issues, it has some drawbacks.
#### Poor TypeScript support
```tsx
import type { FC } from 'react';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
const SubComponent: FC<{ text: string }> = ({ text }) => <>{text}>;
export const Test: FC<{ maybeString?: string }> = ({ maybeString }) => (
    }
        // ❌ TS Error: Type 'string | undefined' is not assignable to type 'string'
        // you have to use `maybeString!` here
    />
);
```
#### Obfuscation of code smells and code cruft
Nested ternaries are easier to spot than nested `` elements.
```tsx
    This is bad}
            />
        )}
        elseShow={'Should be refactored'}
    />
```
Nested operator does not look like other JSX components.
```tsx
    {a ? (
        b ? 
This is bad
 : null
    ) : 'Should be refactored'}
❔
}  // Won't render anything
{!!0 && ❔
}           // Also safe
```
**Unfortunately** Biome (the linter we use) does not include rules to automatically enforce a safer usage of the `&&` operator, as ESLint did.
### Ternary Operator
The ternary operator is a more explicit and safer approach. This covers cases where we need to return `null` or `undefined`.
``` tsx
{NaN ? 👍
 : null}  // Won't render anything
```
It also plays nicely with TypeScript.
```tsx
export const Test: FC<{ maybeString?: string }> = ({ maybeString }) =>
    maybeString ?  : null;
```
This is what we will use from now onwards.
## Consequences
Positive: The codebase will become more type-safe and easier to understand.
Negative: The `` component is imported in nearly 400 files. Significant refactoring effort is required.
Performance: There was no measurable performance difference between code with and without this component. This was tested on production bundle, on the features search (table) and projects list pages.
## Migration plan
1. Mark `` as deprecated in the codebase with a clear JSDoc comment.
2. Automated refactoring with AST (Abstract Syntax Tree):
There already is a script developed that can convert files between `ConditionallyRender` and ternary syntax. It uses jscodeshift, a library. It will be put in `frontend/scripts/transform.js`.
3. Each change will have to be reviewed. The order of refactoring should be:
    1. New features that are behind feature flags.
    2. Non-critical or not in demand pages, like new signals or feedback component.
    3. Less complex pages, for example in `/src/component/admin`.
    4. More complex and critical pages, like strategy editing.
    5. Utilities and components used in many places (`/src/component/common`).
4. Once all instances of `` have been refactored, remove the component from the codebase.