Reputation: 955
Dealt with jsx statement before, so I was pretty confident this worked fine but it seems the skeleton block at the end is shown on mobile as well which is not as intended
{!isMobile &&
!session ?
<NormalComponent />
: data ?
<UserComponent />
: <div className="d-flex flex-column">
<Skeleton width={150} height={28} />
<br /><br />
<Skeleton circle={true} height={65} width={65} className="mr-2" />
</div>
}
the above tries to be the equivalent of:
if (!isMobile) {
if (!session) {
<NormalComponent />
}else{
if (data) {
<UserComponent />
}else{
// show skeleton stuff while it loads data
}
}
}
Upvotes: 0
Views: 340
Reputation: 192507
The statement !isMobile && !session
is considered a single boolean expression, and it effects the 1st ternary. In your case if isMobile
it true
, you don't want to render anything.
Wrap the !session
ternary with parentheses:
const NormalComponent = () => <div>NormalComponent</div>
const UserComponent = () => <div>UserComponent</div>
const Skeleton = (props) => <div {...props}>Skeleton</div>
const Demo = ({ isMobile, session, data }) => (
!isMobile && (
!session ?
<NormalComponent />
: data ?
<UserComponent />
: <div className="d-flex flex-column">
<Skeleton width={150} height={28} />
</div>
)
)
ReactDOM.render(
<React.Fragment>
isMobile is falsy - renders skeleton:
<Demo session />
<br />
isMobile true - render nothing:
<Demo isMobile session />
</React.Fragment>,
root
)
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
A more readable solution would be to use if
, and return as soon as a condition is met:
const NormalComponent = () => <div>NormalComponent</div>
const UserComponent = () => <div>UserComponent</div>
const Skeleton = (props) => <div {...props}>Skeleton</div>
const Demo = ({ isMobile, session, data }) => {
if(isMobile) return null;
if(!session) return <NormalComponent />;
return data ?
<UserComponent />
: (
<div className="d-flex flex-column">
<Skeleton width={150} height={28} />
</div>
);
};
ReactDOM.render(
<React.Fragment>
isMobile is falsy - renders skeleton:
<Demo session />
<br />
isMobile true - render nothing:
<Demo isMobile session />
</React.Fragment>,
root
)
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
Upvotes: 1