Use if else to declare a `let` or `const` to use after the if/else?
I'm not sure why but it seems that I can't call the let
or const
variables if I declare them in an if/else
statement.
if (withBorder) {
const classes = `${styles.circularBorder} ${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`;
} else {
const classes = `${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`;
}
return (
<div className={classes}>
{renderedResult}
</div>
);
If I use this code it says that classes is not defined
.
But if I change the const
to var
classes is defined but I get a warning about classes used outside of binding context
and all var declarations must be at the top of the function scope
How could I fix this?
You should use ternary assignment:
const classes = withBorder ?
`${styles.circularBorder} ${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center` :
`${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`
As specified in other comments/answers let
and const
are blocked scope so that's why they don't work in your example.
For a DRYer code you can also nest the ternary inside string literal:
const classes = `${withBorder ? styles.dimensions: ''} ${styles.circularBorder} ${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`
let
and const
are block level scoped meaning they can only be used within the block they have been defined in ie. { // if defined in here can only be used here }
In this case I would just define above the if/else statement
let classes;
if (withBorder) {
classes = `${styles.circularBorder} ${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`;
} else {
classes = `${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`;
}
Alternative (not sure it's good nor elegant though):
const classes = (() => {
if (withBorder) {
return `${styles.circularBorder}...`;
} else {
return `${styles.dimensions}...`;
}
})();
Don't use an if
-else
-statement but a ternary expression:
const classes = withBorder
? `${styles.circularBorder} ${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`
: `${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`;
Alternatively, just declare it outside of the if
block, which allows you to get rid of the duplication as well:
let classes = `${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`;
if (withBorder) {
classes += ` ${styles.circularBorder}`;
// or if you care about the order,
// classes = `${styles.circularBorder} ${classes}`;
}
Also have a look at messy classnames construction.
let
and const
are block level scoped, so you will have to define them outside of the block. var
works because it hoists out.
You can defined classes
before the if
block like @finalfreq
or
let classes = `${styles.circularBorder} ${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`;
if (withBorder) {
classes += `${styles.circularBorder}`;
}