Flex VS flexGrow VS flexShrink VS flexBase in React Native?

我最后升级了原生的0.42反应,其中包括 flexGrowflexShrinkflexBasis的引入,以及如何呈现 flex的更改(或修复)。

我总是出现这样的错误:

视图是通过显式设置 width/height 呈现的,但是使用了0 ftBase。(这个问题可以通过改变 flex: to flexGrow 来解决:)查看:

有人能解释一下 flex: 1flexGrow: 1的区别吗。如果我将其中一个应用到一个视图,它似乎做不同的事情,但它不应该做同样的事情吗?

84407 次浏览

Here's some test code to consider:

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

Here's a screenshot of the above code:

Screenshot

Added width and 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>;
}

Here's a screenshot of the above code:

Screenshot 2

flex: 0 (default)

  • flex: 0
    • Element takes the size of contents. According to the documentation it should be sized by setting width and height props but it seems to fit to contents if those aren't set.
  • flex: 0, flexBasis: \{\{px}}
    • Element takes the size given by flexBasis
  • flex: 0, flexGrow: 1
    • With flex: 0 and flexGrow: 1; it's the same as adding the size of the contents (in the example above it's a ) to the size of an element that's set to flex: 1. It's similar to flex: 1, flexBasis: 10 except instead of adding a number of pixels you're adding the size of the content.
  • flex: 0, flexShrink: 1
    • With flex: 0 and flexShrink: 1, the element seems to take the size of the content, in other words it's the same as just flex: 0. I'll bet there are situations where it would be bigger than the content but I haven't see that yet.
  • flex: 0, flexGrow: 1, flexBasis: \{\{px}}
    • This is the same as flex: 0, flexGrow: 1 except instead of adding the content size to a flex: 1 element it adds the given number of pixels.
  • flex: 0, flexShrink: 1, flexBasis: \{\{px}}
    • This is the same as flex: 0, flexBasis: \{\{px}}.
  • flex: 0, height: \{\{px}}
    • With flex: 0, height is treated just like flexBasis. If there is both a height and flexBasis are set, height is ignored.

flex: 1

  • flex: 1
  • flex: 1, flexBasis: \{\{px}}
    • With flex: 1 and flexBasis: \{\{px}}; the value of flexBasis is added to the element's size. In other words, it's like taking a flex: 1 element and adding on the number of pixels set by flexBasis. So if a flex: 1 element is 50px, and you add flexBasis: 20 the element will now be 70px.
  • flex: 1, flexGrow: 1
    • ignored
  • flex: 1, flexShrink: 1
    • ignored
  • flex: 1, flexGrow: 1, flexBasis: \{\{px}}
    • This is the same as flex: 1, flexBasis: \{\{px}} since flexGrow is ignored.
  • flex: 1, flexShrink: 1, flexBasis: \{\{px}}
    • This is the same as flex: 1, flexBasis: \{\{px}} since flexShrink is ignored.
  • flex: 1, height: \{\{px}}
    • With flex: 1, height is ignored. Use flexBasis instead.

Here are my observations:

  • Trouble Shooting Tip: Make sure the parent view(s) are giving the children room to grow/shrink. Notice the flex: 1 on the parent view, without it, all the children don't display as you'd expect.
  • Trouble Shooting Tip: Don't use Hot Reloading when testing these values, it can display elements incorrectly after it's reloaded a few times. I recommend enabling Live Reload or using command + r (a lot).
  • The default flex value is flex: 0. If you don't add a flex style value it defaults to 0.
  • Trouble Shooting Tip: if you're tryign to figure out why something isn't displaying like you think it should, start with the (most) parent element and make sure it's giving enough space to it's children to do what they need to do. In other words, try setting it to flex:1 and see if that helps, then go to the next child and repeat.
  • It seems like width is always considered with flexDirection: "column" no matter the other flex props. The same applies for height with flexDirection: "row".
  • After running these test, in general I would use flexBasis over height since flexBasis trumps height.