0

I have the following logic inside a react component where, I am rendering different component based on the boolean values. This peace of code is very difficult to understand. Are there anyways, I can simply that logic:

      {isEnabled ? (
      <>
        {!loading ? (
          <>
            {items.length === 0 ? (
              <>
                <ComponentOne/>
                <Container>
                  <img src={Image} alt="Image" />
                </Container>
              </>
            ) : (
              <ComponentTwo/>
            )}
          </>
        ) : (
          <div>
            <LoadingComponent/>
          </div>
        )}
      </>
    ) : (
      <ComponentThree/>
    )}
2
  • Are you facing any issue or you want to improve the logic? Commented Oct 28, 2021 at 10:13
  • I want to improve that logic, as it's seems to very difficult to read and understand. Commented Oct 28, 2021 at 10:14

4 Answers 4

1

I'd probably split it up into seperate components and pass parameters down the component tree for example

{isEnabled ? <IsLoadingComponent loading={loading} items={items}> : <ComponentThree/>}
Sign up to request clarification or add additional context in comments.

Comments

1

You might find it useful to split the component up into a "Loading" version and a "Loaded" version so you don't have to handle both states in the same component. Then the component basically just renders the "Loading" or "Loaded" version depending on the flag.

But even without that, you can at least make that easier to debug by using if/else if etc. and assigning to a temporary variable:

let comp;
if (isEnabled) {
    if (loading) {
        comp = <div>
            <LoadingComponent/>
        </div>;
    } else if (items.length === 0) {
        comp = <>
            <ComponentOne/>
            <Container>
                <img src={Image} alt="Image" />
            </Container>
        </>;
    } else {
        comp = <ComponentTwo />;
    }
} else {
    comp = <ComponentThree />;
}

Then just

{comp}

where that nested conditional was.

Comments

0

I think you are making a simple thing very complicated. What we can do instead is that make use of "&&".

  { isEnabled && loading && <LoaderComponent /> }
   {isEnabled && !items.length  &&
     <>
     <ComponentOne/>
     <Container>
        <img src={Image} alt="Image" />
     </Container>
  </>
}
{isEnabled && items.length && <ComponentTwo/>}
{!isEnabled && <ComponentThree />}

1 Comment

This still doesn't do what the original does. To do what the original does, it would need to repeat the test of loading in various places. (For instance: During loading, this renders either ComponentOne [as part of a fragment] or ComponentTwo depending on items.length, but neither should be rendered if loading is true.) It's great to show an alternative and I like the direction this tries to go, but to me it' simportant that it handle the same cases as the original.
0

Though I want to support the argument the others made (split into multiple components), you can already achieve a bit more readability by dropping unnecessary fragments (<></>) and/or parenthesis and by using "better"(opinion) indentation.

return (
  isEnabled
    ? loading
      ? <div><LoadingComponent/></div>
      : items.length === 0
        ? <> {/* this is the only place a fragment is actually needed */}
          <ComponentOne/>
          <Container>
            <img src={Image} alt="Image"/>
          </Container>
        </>
        : <ComponentTwo/>
    : <ComponentThree/>
);

Alternatively, early returns do help a lot with readability. For example:

const SomeComponent = () => {
  // ...snip...

  if (!isEnabled) {
    return <ComponentThree/>;
  }

  if (loading) {
    return <div><LoadingComponent/></div>;
  }

  if (items.length > 0) {
    return <ComponentThree/>;
  }

  return (
    <>
      <ComponentOne/>
      <Container>
        <img src={Image} alt="Image"/>
      </Container>
    </>
  );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.