Home > Mobile >  Third condition in ternery operator doesn't render when condition is met
Third condition in ternery operator doesn't render when condition is met

Time:02-02

Trying to figure out where I am going wrong with this ternery.

It isn't rendering the last element (blurredscreen) if authStatus !== "authenticated".

  return (
      <>
        <div key={"key-"   id}>
          {isOpen && (
            <div>
              {authStatus === "authenticated" &&
                (header.x && header.x.t === "abc" ? (
                  <div
                    onClick={(e) => {
                      e.stopPropagation();
                    }}
                  >
                    <ComponentOne />
                  </div>
                ) : header.x && header.x.t === "def" ? (
                  <div
                    onClick={(e) => {
                      e.stopPropagation();
                    }}
                  >
                    <ComponentTwo />
                  </div>
                ) : ( //this is the part that doesn't display when condition is met
                  authStatus !== "authenticated" &&
                  !header.x && (
                    <div>
                      <img
                        src={blurredScreen}
                       />
                      <button
                        onClick={handleSignInClick}
                      >
                        <span style={{ textAlign: "left" }}>Login </span>
                      </button>
                    </div>
                  )
                ))}
            </div>
          )}
        </div>
      </>
    );

CodePudding user response:

Overuse of tenery operator in JSX can lead to really confusing code and makes it hard to debug. The posters question is a good example, there are only 3 conditional routes and the code looks very confusing, as you can imagine this only gets more complicated with 4,5 .. etc.

The good news, you can still use if else inside React, just assign your JSX to a local variable and render this.

Below is a simple example that flips between 3 states, and as you can see is much easier to reason with.

const {useEffect, useState, Fragment} = React;


function Demo() {
  const [s, setS] = useState(0);
  
  useEffect(() => {
    const t = setInterval(() => setS(c => c  1), 1000);
    return () => { clearInterval(t) }
  }, []);
  
  let render = null;
  let d = s % 3;
  
  if (d === 0) {
    render = <div>This is 0</div>
  } else if (d ===1) {
    render = <div>This is One</div>
  } else {
    render = <div>Everything else</div>
  }
  
  //Fragment used here, because SO Snippet
  //do not transpile <>....</>
  return <Fragment>{render}</Fragment>
}


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Demo/>);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>


<div id="root"></div>

Also notice I set let render = null;, this is deliberate, null is a valid JSX type that renders nothing. So if for some reason no code paths are met, React will render nothing instead of throwing an error. Of course in the above example that's not going to happen, but it's good habit to get into. If your on React 18, you can now leave out the null. https://blog.saeloun.com/2022/04/14/react-18-allows-components-to-render-undfined.html

  • Related