web-dev-qa-db-fra.com

Utilisez if else pour déclarer un `let` ou` const` à utiliser après le if / else?

Je ne sais pas pourquoi mais il semble que je ne puisse pas appeler les variables let ou const si je les déclare dans un if/else déclaration.

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>
);

Si j'utilise ce code, il est dit que classes is not defined.

Mais si je change les classes const en var est défini mais je reçois un avertissement sur classes used outside of binding contextet all var declarations must be at the top of the function scope

Comment pourrais-je résoudre ce problème?

25
Johhan Santana

Vous devez utiliser l'affectation ternaire:

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`

Comme spécifié dans d'autres commentaires/réponses let et const sont des portées bloquées, c'est pourquoi ils ne fonctionnent pas dans votre exemple.

Pour un code DRYer, vous pouvez également imbriquer le littéral de chaîne interne ternaire:

 const classes = `${withBorder ? styles.dimensions: ''} ${styles.circularBorder} ${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`
30
maioman

let et const sont étendues au niveau du bloc, ce qui signifie qu'elles ne peuvent être utilisées que dans le bloc dans lequel elles ont été définies. { // if defined in here can only be used here }

Dans ce cas, je définirais simplement ci-dessus l'instruction if/else

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`;
}
30
finalfreq

Alternative (pas sûr que ce soit bon ni élégant cependant):

const classes = (() => {
    if (withBorder) {
      return `${styles.circularBorder}...`;
    } else {
      return `${styles.dimensions}...`;
    }
})();
7
rap-2-h

N'utilisez pas une instruction if-else- mais une expression ternaire:

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`;

Alternativement, déclarez-le simplement en dehors du bloc if, ce qui vous permet également de vous débarrasser de la duplication:

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}`;
}

Jetez également un œil à construction de noms de classe en désordre .

3
Bergi

let et const ont une portée au niveau du bloc, vous devrez donc les définir en dehors du bloc. var fonctionne car il se hisse.

Vous pouvez définir classes avant le bloc if comme @ finalfreq

ou

let classes = `${styles.circularBorder} ${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`;

if (withBorder) {
  classes += `${styles.circularBorder}`;
}
3
antyang

La norme ESLint aime les opérateurs au début de la ligne. Les conditions longues doivent également être résumées, sauf dans une boucle de temps informatique.

Dans ce cas particulier, les chaînes sont également longues, donc je les résumerais aussi. Le problème avec la manière de Bergi est que la plupart des linters vont paralyser son style, pour des raisons de conformité.

De cette façon, tout reste normal et facile à lire, si vous connaissez les ternaires, ce que vous devriez être.

const styleWithBorder = `${styles.circularBorder} ${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`
const styleWithoutBorder = `${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`
const classes = isBorderedElement ? [ styleWithBorder ] : [ styleWithoutBorder ]
1
Ray Foss

Simple, faites simplement ceci:

const genericStyle = `${styles.dimensions} ${styles.circularPadding} row flex-items-xs-middle flex-items-xs-center`,

classes = withBorder ? `${styles.circularBorder} ${genericStyle}` : genericStyle;

return (
  <div className={classes}>
    {renderedResult}
  </div>
);

Cela a aussi du nettoyage, la classe utilisée deux fois et seulement circularBorder est la différence ...

0
Alireza