web-dev-qa-db-fra.com

flex vs flexGrow vs flexShrink vs flexBasis dans React Native?

J'ai finalement mis à niveau la version 0.42 native, ce qui inclut l'introduction de flexGrow, flexShrink et flexBasis, ainsi que la modification (ou le correctif) de la manière dont flex est rendu.

Je continue à avoir des erreurs comme:

La vue a été rendue avec une largeur/hauteur explicitement définie, mais avec un 0 flexBasis. (Cela peut être corrigé en changeant flex: en flexGrow :) Voir:

Quelqu'un peut-il expliquer la différence entre flex: 1 et flexGrow: 1. Si j'applique l'un ou l'autre à une vue, elle semble faire des choses différentes, mais ne devrait-elle pas en faire autant?

53
Dev01

Voici un code de test à considérer:

_render() {
    return <View style={{flex: 1,backgroundColor: "cornflowerblue"}}>
        <View style={{backgroundColor: "chartreuse"}}><Text>Nothing (17px)</Text></View>

        <View style={{flex: 0, backgroundColor: "yellow"}}><Text>flex: 0 (17px)</Text></View>

        <View style={{flex: 0, flexBasis: 10, backgroundColor: "brown"}}><Text>flex: 0, flexBasis: 10 (10px)</Text></View>
        <View style={{flex: 0, flexGrow: 1, backgroundColor: "orange"}}><Text>flex: 0, flexGrow: 1 (97px)</Text></View>
        <View style={{flex: 0, flexShrink: 1, backgroundColor: "tan"}}><Text>flex: 0, flexShrink: 1 (17px)</Text></View>
        <View style={{flex: 0, flexGrow: 1, flexBasis: 10, backgroundColor: "purple"}}><Text>flex: 0, flexGrow: 1, flexBasis: 10 (90px)</Text></View>
        <View style={{flex: 0, flexShrink: 1, flexBasis: 10, backgroundColor: "gray"}}><Text>flex: 0, flexShrink: 1, flexBasis: 10 (10px with 7px hidden below the next element)</Text></View>

        <View style={{flex: 1, backgroundColor: "blue"}}><Text>flex: 1 (80px)</Text></View>

        <View style={{flex: 1, flexBasis: 10, backgroundColor: "cornsilk"}}><Text>flex: 1, flexBasis: 10 (90px)</Text></View>
        <View style={{flex: 1, flexGrow: 1, backgroundColor: "red"}}><Text>flex: 1, flexGrow: 1 (80px)</Text></View>
        <View style={{flex: 1, flexShrink: 1, backgroundColor: "green"}}><Text>flex: 1, flexShrink: 1 (80px)</Text></View>
        <View style={{flex: 1, flexGrow: 1, flexBasis: 10, backgroundColor: "aqua"}}><Text>flex: 1, flexGrow: 1, flexBasis: 10 (90px)</Text></View>
        <View style={{flex: 1, flexShrink: 1, flexBasis: 10, backgroundColor: "pink"}}><Text>flex: 1, flexShrink: 1, flexBasis: 10 (90px)</Text></View>
    </View>;
}
_

Voici une capture d'écran du code ci-dessus:

Screenshot

Ajouté width et height:

_render() {
    return <View style={{flex: 1,backgroundColor: "cornflowerblue"}}>
        <View style={{flex: 0, backgroundColor: "orange"}}><Text>flex: 0 (17px)</Text></View>
        <View style={{flex: 0, width: 700, height: 20, backgroundColor: "yellow"}}><Text>flex: 0, width: 700, height: 20 (20px)</Text></View>

        <View style={{flex: 0, flexBasis: 10, width: 700, height: 20, backgroundColor: "brown"}}><Text>flex: 0, flexBasis: 10, width: 700, height: 20 (10px with 7px hidden below the next element)</Text></View>
        <View style={{flex: 0, flexGrow: 1, width: 700, height: 20, backgroundColor: "orange"}}><Text>flex: 0, flexGrow: 1, width: 700, height: 20 (90px)</Text></View>
        <View style={{flex: 0, flexShrink: 1, width: 700, height: 20, backgroundColor: "tan"}}><Text>flex: 0, flexShrink: 1, width: 700, height: 20 (20px)</Text></View>
        <View style={{flex: 0, flexGrow: 1, flexBasis: 10, width: 700, height: 20, backgroundColor: "purple"}}><Text>flex: 0, flexGrow: 1, flexBasis: 10, width: 700, height: 20 (80px)</Text></View>
        <View style={{flex: 0, flexShrink: 1, flexBasis: 10, width: 700, height: 20, backgroundColor: "gray"}}><Text>flex: 0, flexShrink: 1, flexBasis: 10, width: 700, height: 20 (10px with 7px hidden below the next element)</Text></View>

        <View style={{flex: 1, backgroundColor: "orange"}}><Text>flex: 1 (70px)</Text></View>
        <View style={{flex: 1, width: 700, height: 20, backgroundColor: "blue"}}><Text>flex: 1, width: 700, height: 20 (70px)</Text></View>

        <View style={{flex: 1, flexBasis: 10, width: 700, height: 20, backgroundColor: "cornsilk"}}><Text>flex: 1, flexBasis: 10, width: 700, height: 20 (80px)</Text></View>
        <View style={{flex: 1, flexGrow: 1, width: 700, height: 20, backgroundColor: "red"}}><Text>flex: 1, flexGrow: 1, width: 700, height: 20 (70px)</Text></View>
        <View style={{flex: 1, flexShrink: 1, width: 700, height: 20, backgroundColor: "green"}}><Text>flex: 1, flexShrink: 1, width: 700, height: 20 (70px)</Text></View>
        <View style={{flex: 1, flexGrow: 1, flexBasis: 10, width: 700, height: 20, backgroundColor: "aqua"}}><Text>flex: 1, flexGrow: 1, flexBasis: 10, width: 700, height: 20 (80px)</Text></View>
        <View style={{flex: 1, flexShrink: 1, flexBasis: 10, width: 700, height: 20, backgroundColor: "pink"}}><Text>flex: 1, flexShrink: 1, flexBasis: 10, width: 700, height: 20 (80px)</Text></View>
    </View>;
}
_

Voici une capture d'écran du code ci-dessus:

Screenshot 2

_flex: 0_ (par défaut)

  • flex: 0
    • L'élément prend la taille du contenu. Selon la documentation , il devrait être redimensionné en définissant width et height props, mais il semble correspondre au contenu si ceux-ci ne sont pas définis.
  • flex: 0, flexBasis: {{px}}
    • L'élément prend la taille donnée par flexBasis
  • flex: 0, flexGrow: 1
    • Avec _flex: 0_ et _flexGrow: 1_; Cela revient à ajouter la taille du contenu (dans l'exemple ci-dessus, il s'agit d'un a) à la taille d'un élément défini sur _flex: 1_. Cela ressemble à _flex: 1, flexBasis: 10_ sauf qu'au lieu d'ajouter un nombre de pixels, vous ajoutez la taille du contenu.
  • flex: 0, flexShrink: 1
    • Avec _flex: 0_ et _flexShrink: 1_, l'élément semble prendre la taille du contenu, c'est-à-dire qu'il est identique à _flex: 0_. Je parie qu'il y a des situations où il serait plus grand que le contenu mais je ne l'ai pas encore vu.
  • flex: 0, flexGrow: 1, flexBasis: {{px}}
    • Ceci est identique à _flex: 0, flexGrow: 1_ sauf qu'au lieu d'ajouter la taille du contenu à un élément _flex: 1_, il ajoute le nombre donné de pixels.
  • flex: 0, flexShrink: 1, flexBasis: {{px}}
    • Ceci est identique à _flex: 0, flexBasis: {{px}}_.
  • flex: 0, height: {{px}}
    • Avec _flex: 0_, height est traité comme flexBasis. S'il y a à la fois height et flexBasis sont définis, height est ignoré.

_flex: 1_

  • flex: 1
  • flex: 1, flexBasis: {{px}}
    • Avec _flex: 1_ et _flexBasis: {{px}}_; la valeur de flexBasis est ajoutée à la taille de l'élément. En d'autres termes, cela revient à prendre un élément _flex: 1_ et à ajouter le nombre de pixels défini par flexBasis. Donc, si un élément _flex: 1_ est 50px et que vous ajoutez _flexBasis: 20_, l'élément sera désormais 70px.
  • flex: 1, flexGrow: 1
    • ignoré
  • flex: 1, flexShrink: 1
    • ignoré
  • flex: 1, flexGrow: 1, flexBasis: {{px}}
    • Ceci est identique à _flex: 1, flexBasis: {{px}}_ puisque flexGrow est ignoré.
  • flex: 1, flexShrink: 1, flexBasis: {{px}}
    • Ceci est identique à _flex: 1, flexBasis: {{px}}_ puisque flexShrink est ignoré.
  • flex: 1, height: {{px}}
    • Avec _flex: 1_, height est ignoré. Utilisez flexBasis à la place.

Voici mes observations:

  • Conseil de dépannage: Assurez-vous que la ou les vues parent (s) donnent aux enfants suffisamment de place pour grandir/réduire. Notez le _flex: 1_ sur la vue parent. Sans elle, tous les enfants ne s'afficheront pas comme prévu.
  • Conseil de dépannage: N'utilisez pas _Hot Reloading_ lors du test de ces valeurs, il risque d'afficher des éléments de manière incorrecte après quelques recharges. Je recommande d'activer _Live Reload_ ou d'utiliser command + r (beaucoup).
  • La valeur de flex par défaut est _flex: 0_. Si vous n'ajoutez pas de valeur de style flex, sa valeur par défaut est 0.
  • Astuce de dépannage: si vous essayez de comprendre pourquoi quelque chose ne s'affiche pas comme vous le pensez, commencez par l'élément parent (le plus) et assurez-vous que les enfants aient suffisamment d’espace pour faire ce qu’ils doivent faire. En d’autres termes, essayez de le mettre en flexion: 1 et voyez si cela vous aide, puis passez à l’enfant suivant et recommencez.
  • Il semble que width soit toujours pris en compte avec _flexDirection: "column"_, quels que soient les autres accessoires de flexion. Il en va de même pour height avec _flexDirection: "row"_.
  • Après avoir exécuté ces tests, en général, j'utiliserais flexBasis sur height puisque flexBasis l'emporte sur height.
145
Dev01