DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Discussion on: A Clean Way to Conditionally Render Components

anxiny profile image
Anxin.Y Author

I just don't like the {...} things inside my JSX, it just doesn't look nice in terms of format.

Thread Thread
lukeshiru profile image
Luke Shiru

JSX will always end up with {...} somewhere. You can always use stuff like Svelte, that already includes "if" in their templating ☺️

Thread Thread
hvolschenk profile image
Hendrik Volschenk

I wanted to add the same comment about the content of the <If> being evaluated immediately
and got some quite surprising results.

See here: codesandbox.io/s/if-component-b5zxk

Thread Thread
anxiny profile image
Anxin.Y Author

Yes, a good example of how it works

Thread Thread
lukeshiru profile image
Luke Shiru

If you understand the underlying code for React, then this is no surprise. When you write:

import { Fragment } from "react";

const If = ({ children, condition }) =>
    condition ? <Fragment>{children}</Fragment> : undefined;

const DisplayData = ({ data }) => <Fragment>{data}</Fragment>;

const data = undefined;

export default (
    <If condition={data}>
        <DisplayData data={data} />
    </If>
);
Enter fullscreen mode Exit fullscreen mode

You're actually writing this:

import { jsx } from "react/jsx-runtime";
import { Fragment } from "react";

const If = ({ children, condition }) =>
    condition ? jsx(Fragment, { children }) : undefined;

const DisplayData = ({ data }) => jsx(Fragment, { children: data });

const data = undefined;

// The important bit:
export default jsx(If, {
    condition: data,
    children: jsx(DisplayData, { data }),
});
Enter fullscreen mode Exit fullscreen mode

Compared to doing it with a ternary like this:

import { Fragment } from "react";

const DisplayData = ({ data }) => <Fragment>{data}</Fragment>;

const data = undefined;

export default data ? <DisplayData data={data} /> : undefined;
Enter fullscreen mode Exit fullscreen mode

That's like writing this:

import { jsx } from "react/jsx-runtime";
import { Fragment } from "react";

const DisplayData = ({ data }) => jsx(Fragment, { children: data });

const data = undefined;

// The important bit:
export default data ? jsx(DisplayData, { data }) : undefined;
Enter fullscreen mode Exit fullscreen mode

With If you always call jsx with DisplayData passing data, without If you only do that call if data exists, if not you don't do anything.