2

So I read a book about react tips and tricks lately and it says

//  Avoid: all the JSX written here will get compiled 
// even though it is on the false branch
const Component1 = ({ isLoggedIn }) => {
  return (
    <>
      {isLoggedIn && <div /*a lot of JSX */ />}
      {!isLoggedIn && <div /*a lot of JSX */ />}
    </>
  );
};

//  Good: one of the 2 components does not get mounted
const Component2 = ({ isLoggedIn }) => {
  return (
    <>
      {isLoggedIn && <LoggedInComponent />}
      {!isLoggedIn && <NotLoggedInComponent />}
    </>
  );
};

From the book:

If you put all the JSX in one component, all the JSX in all the branches will get compiled even though it is in the "no branch".
Instead having different components for different conditions will mount only the component for the true one.

I get the point here, but its not clear to me. What really happens here? Why component1 is a bad practice and should avoid it? For me both of these components looks identical to me.

Charitha Goonewardena
  • 4,418
  • 2
  • 36
  • 38
  • 2
    I think the main concern here is file size. Imagine more JSX markup than just the `div` in the example: JSX compiles to `React.createElement` calls for every JSX element. This means if you have a lot of JSX markup in a single file your compiled file will grow big quite easily. If `isLoggedIn` is false it wouldn't render or execute anything in the `!isLoggedIn` statement, but the code would still be in the compiled file. – RobertMulders Oct 04 '22 at 06:27

1 Answers1

3

To be more precise with the terms used here:

Avoid: all the JSX written here will get compiled

In JSX context, the compiler transpiles JSX syntactic sugar to equivalent JS code.

"...takes the source code of a program written in a programming language as its input and produces an equivalent source code in the same or a different programming language". wiki

While "compiled" usually (always) refers to compilation step.

"...primarily used for programs that translate source code from a high-level programming language to a lower level language". wiki


What really happens here?

Babel used as JSX compiler that transpiles the above JSX:

// Author's claim to avoid
const Component1 = ({ isLoggedIn }) => {
  return React.createElement(
    React.Fragment,
    null,
    isLoggedIn &&
      React.createElement(
        "div",
        null,
        React.createElement("h1", null, "Example")
      ),
    !isLoggedIn &&
      React.createElement(
        "div",
        null,
        React.createElement("h1", null, "Example not logged in"),
        React.createElement("div", null, "Some another div"),
        React.createElement(SomeComponent, null)
      )
  );
};

// Author's claim to write
const Component2 = ({ isLoggedIn }) => {
  return React.createElement(
    React.Fragment,
    null,
    isLoggedIn && React.createElement(LoggedInComponent, null),
    !isLoggedIn && React.createElement(NotLoggedInComponent, null)
  );
};

The author nitpicking on redundant memory consumption of the "not used branch" (!isLoggedIn) when transpiling HTML tags instead of converting them to components.

Why component1 is a bad practice and should avoid it?

Its not bad practice (at least where I work), you shouldn't avoid it, keep focusing on readable code.

Author's opinion is on same scale of nintpicking on declaring constant inside render function:

const Component1 = () => {
  const x = 5;
  return <div>{x}</div>;
};

const x = 5;
const Component2 = () => {
  return <div>{x}</div>;
};

There are thousands of similar questions and discussions around the "premature optimization is the root of all evil" topic (lookup for the term).

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
  • Oh, it makes sense, but leads to another question. In Component2, even though one of the components is not mounted, both should be compiled right? If so the output from the babel traspilation isn't same as Component1 output? – Charitha Goonewardena Oct 04 '22 at 07:13
  • Same output as in the example – Dennis Vash Oct 04 '22 at 09:13
  • 3
    Is the book you're reading _React Tips and Tricks_ by any chance? If so, I'd consider consulting a different resource; I've seen many of the author's posts on LinkedIn, and a good deal of his understanding of React and JavaScript is either misguided or outright incorrect. – James Wright Oct 04 '22 at 12:15
  • 2
    For reference: I'm here after seeing his post on "blind branches" and can say that they aren't anything to worry about; even by abstracting element trees in components they'll still eventually be transpiled and bundled. There could be an impact when using dynamic imports on the client or importing components in server-side code, but I wouldn't worry about that unless there were a clear performance issue. – James Wright Oct 04 '22 at 12:23