I finally upgraded react native to 0.42 which includes the introduction of flexGrow
, flexShrink
, and flexBasis
and the change (or fix) of how flex
is rendered.
I keep getting errors like:
View was rendered with explicitly set width/height but with a 0 flexBasis. (This might be fixed by changing flex: to flexGrow:) View:
Can someone explain the difference between flex: 1
vs flexGrow: 1
. If I apply one or the other to a View it seems to do different things but shouldn't it do the same?
Flex Basis, Grow, and Shrink Setting the flexBasis of a child is similar to setting the width of that child if its parent is a container with flexDirection: row or setting the height of a child if its parent is a container with flexDirection: column .
In React Native, Flexbox is the same as it is for basic CSS. The only difference being in default values. flexDirection: The default value for CSS is row whereas the default value in React Native is column. alignContent: The default value for CSS is stretch the default value in React Native is flex-start.
Normally you will use flex: 1 , which tells a component to fill all available space, shared evenly amongst other components with the same parent. The larger the flex given, the higher the ratio of space a component will take compared to its siblings.
flex is a shorthand property of flex-grow , flex-shrink and flex-basis . Then, the difference is that the flex base size will be 0 in the first case, so the flex items will have the same size after distributing free space.
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:
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:
flex: 0
(default)flex: 0
width
and height
props but it seems to fit to contents if those aren't set.flex: 0, flexBasis: {{px}}
flexBasis
flex: 0, flexGrow: 1
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
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}}
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}}
flex: 0, flexBasis: {{px}}
.flex: 0, height: {{px}}
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}}
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
flex: 1, flexShrink: 1
flex: 1, flexGrow: 1, flexBasis: {{px}}
flex: 1, flexBasis: {{px}}
since flexGrow
is ignored.flex: 1, flexShrink: 1, flexBasis: {{px}}
flex: 1, flexBasis: {{px}}
since flexShrink
is ignored.flex: 1, height: {{px}}
flex: 1
, height
is ignored. Use flexBasis
instead.flex: 1
on the parent view, without it, all the children don't display as you'd expect.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). flex: 0
. If you don't add a flex style value it defaults to 0.width
is always considered with flexDirection: "column"
no matter the other flex props. The same applies for height
with flexDirection: "row"
.flexBasis
over height
since flexBasis
trumps height
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With