React Native 中的 flex vs flexGrow vs flexShrink vs flexBasis?
flex vs flexGrow vs flexShrink vs flexBasis in React Native?
我最终将 React Native 升级到 0.42,其中包括 flexGrow
、flexShrink
和 flexBasis
的引入以及 flex
的更改(或修复)渲染。
我不断收到如下错误:
View was rendered with explicitly set width/height but with a 0 flexBasis. (This might be fixed by changing flex: to flexGrow:) View:
有人可以解释一下 flex: 1
和 flexGrow: 1
之间的区别吗?如果我将一个或另一个应用于视图,它似乎会做不同的事情,但它不应该做同样的事情吗?
这里有一些测试代码需要考虑:
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>;
}
下面是上面代码的截图:
添加了 width
和 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>;
}
下面是上面代码的截图:
flex: 0
(默认)
flex: 0
- 元素占用内容的大小。根据 documentation 它应该通过设置
width
和 height
属性来调整大小,但如果没有设置它们似乎适合内容。
flex: 0, flexBasis: {{px}}
- 元素采用
flexBasis
给定的大小
flex: 0, flexGrow: 1
- 与
flex: 0
和flexGrow: 1
;这与将内容的大小(在上面的示例中为 a )添加到设置为 flex: 1
的元素的大小相同。它与 flex: 1, flexBasis: 10
类似,只是您添加的不是像素数量,而是内容的大小。
flex: 0, flexShrink: 1
- 对于
flex: 0
和 flexShrink: 1
,元素似乎占用内容的大小,换句话说,它与 flex: 0
相同。我敢打赌,在某些情况下它会比内容更大,但我还没有看到。
flex: 0, flexGrow: 1, flexBasis: {{px}}
- 这与
flex: 0, flexGrow: 1
相同,只是不是将内容大小添加到 flex: 1
元素,而是添加给定的像素数。
flex: 0, flexShrink: 1, flexBasis: {{px}}
- 这与
flex: 0, flexBasis: {{px}}
相同。
flex: 0, height: {{px}}
- 对于
flex: 0
,height
的处理方式与 flexBasis
相同。如果同时设置了 height
和 flexBasis
,则忽略 height
。
flex: 1
flex: 1
- 元素可用 space。有关详细信息,请参阅 Layout Props documentation
flex: 1, flexBasis: {{px}}
- 与
flex: 1
和flexBasis: {{px}}
; flexBasis
的值被添加到元素的大小。换句话说,这就像采用 flex: 1
元素并添加 flexBasis
设置的像素数。因此,如果 flex: 1
元素为 50px,而您添加 flexBasis: 20
元素现在将为 70px。
flex: 1, flexGrow: 1
- 忽略
flex: 1, flexShrink: 1
- 忽略
flex: 1, flexGrow: 1, flexBasis: {{px}}
- 这与
flex: 1, flexBasis: {{px}}
相同,因为 flexGrow
被忽略。
flex: 1, flexShrink: 1, flexBasis: {{px}}
- 这与
flex: 1, flexBasis: {{px}}
相同,因为 flexShrink
被忽略。
flex: 1, height: {{px}}
- 与
flex: 1
,height
被忽略。请改用 flexBasis
。
以下是我的观察:
- 故障排除提示:确保 parent 视图给 children 空间给 grow/shrink。请注意 parent 视图上的
flex: 1
,没有它,所有 children 都不会像您期望的那样显示。
- 故障排除提示:测试这些值时不要使用
Hot Reloading
,它会在重新加载几次后显示不正确的元素。我建议启用 Live Reload
或使用 command + r(很多)。
- 默认弹性值为
flex: 0
。如果你不添加 flex 样式值,它默认为 0。
- 故障排除提示:如果您想要弄清楚为什么某些内容没有像您认为的那样显示,请从(大多数)parent 开始元素,并确保它给 space 足够的 children 来做他们需要做的事情。换句话说,尝试将其设置为 flex:1 并查看是否有帮助,然后转到下一个 child 并重复。
- 似乎
width
总是与 flexDirection: "column"
一起考虑,无论其他 flex 道具如何。这同样适用于 height
和 flexDirection: "row"
。
- 在 运行 这些测试之后,通常我会使用
flexBasis
而不是 height
,因为 flexBasis
胜过 height
。
我最终将 React Native 升级到 0.42,其中包括 flexGrow
、flexShrink
和 flexBasis
的引入以及 flex
的更改(或修复)渲染。
我不断收到如下错误:
View was rendered with explicitly set width/height but with a 0 flexBasis. (This might be fixed by changing flex: to flexGrow:) View:
有人可以解释一下 flex: 1
和 flexGrow: 1
之间的区别吗?如果我将一个或另一个应用于视图,它似乎会做不同的事情,但它不应该做同样的事情吗?
这里有一些测试代码需要考虑:
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>;
}
下面是上面代码的截图:
添加了 width
和 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>;
}
下面是上面代码的截图:
flex: 0
(默认)
flex: 0
- 元素占用内容的大小。根据 documentation 它应该通过设置
width
和height
属性来调整大小,但如果没有设置它们似乎适合内容。
- 元素占用内容的大小。根据 documentation 它应该通过设置
flex: 0, flexBasis: {{px}}
- 元素采用
flexBasis
给定的大小
- 元素采用
flex: 0, flexGrow: 1
- 与
flex: 0
和flexGrow: 1
;这与将内容的大小(在上面的示例中为 a )添加到设置为flex: 1
的元素的大小相同。它与flex: 1, flexBasis: 10
类似,只是您添加的不是像素数量,而是内容的大小。
- 与
flex: 0, flexShrink: 1
- 对于
flex: 0
和flexShrink: 1
,元素似乎占用内容的大小,换句话说,它与flex: 0
相同。我敢打赌,在某些情况下它会比内容更大,但我还没有看到。
- 对于
flex: 0, flexGrow: 1, flexBasis: {{px}}
- 这与
flex: 0, flexGrow: 1
相同,只是不是将内容大小添加到flex: 1
元素,而是添加给定的像素数。
- 这与
flex: 0, flexShrink: 1, flexBasis: {{px}}
- 这与
flex: 0, flexBasis: {{px}}
相同。
- 这与
flex: 0, height: {{px}}
- 对于
flex: 0
,height
的处理方式与flexBasis
相同。如果同时设置了height
和flexBasis
,则忽略height
。
- 对于
flex: 1
flex: 1
- 元素可用 space。有关详细信息,请参阅 Layout Props documentation
flex: 1, flexBasis: {{px}}
- 与
flex: 1
和flexBasis: {{px}}
;flexBasis
的值被添加到元素的大小。换句话说,这就像采用flex: 1
元素并添加flexBasis
设置的像素数。因此,如果flex: 1
元素为 50px,而您添加flexBasis: 20
元素现在将为 70px。
- 与
flex: 1, flexGrow: 1
- 忽略
flex: 1, flexShrink: 1
- 忽略
flex: 1, flexGrow: 1, flexBasis: {{px}}
- 这与
flex: 1, flexBasis: {{px}}
相同,因为flexGrow
被忽略。
- 这与
flex: 1, flexShrink: 1, flexBasis: {{px}}
- 这与
flex: 1, flexBasis: {{px}}
相同,因为flexShrink
被忽略。
- 这与
flex: 1, height: {{px}}
- 与
flex: 1
,height
被忽略。请改用flexBasis
。
- 与
以下是我的观察:
- 故障排除提示:确保 parent 视图给 children 空间给 grow/shrink。请注意 parent 视图上的
flex: 1
,没有它,所有 children 都不会像您期望的那样显示。 - 故障排除提示:测试这些值时不要使用
Hot Reloading
,它会在重新加载几次后显示不正确的元素。我建议启用Live Reload
或使用 command + r(很多)。 - 默认弹性值为
flex: 0
。如果你不添加 flex 样式值,它默认为 0。 - 故障排除提示:如果您想要弄清楚为什么某些内容没有像您认为的那样显示,请从(大多数)parent 开始元素,并确保它给 space 足够的 children 来做他们需要做的事情。换句话说,尝试将其设置为 flex:1 并查看是否有帮助,然后转到下一个 child 并重复。
- 似乎
width
总是与flexDirection: "column"
一起考虑,无论其他 flex 道具如何。这同样适用于height
和flexDirection: "row"
。 - 在 运行 这些测试之后,通常我会使用
flexBasis
而不是height
,因为flexBasis
胜过height
。