React Native 中的 flex vs flexGrow vs flexShrink vs flexBasis?

Posted

技术标签:

【中文标题】React Native 中的 flex vs flexGrow vs flexShrink vs flexBasis?【英文标题】:flex vs flexGrow vs flexShrink vs flexBasis in React Native? 【发布时间】:2017-08-25 21:03:44 【问题描述】:

我终于将 react native 升级到 0.42,其中包括 flexGrowflexShrinkflexBasis 的引入以及 flex 呈现方式的更改(或修复)。

我不断收到如下错误:

视图以显式设置的宽度/高度呈现,但 flexBasis 为 0。 (这可以通过将 flex: 更改为 flexGrow 来解决:)查看:

谁能解释flex: 1flexGrow: 1 之间的区别。如果我将其中一个应用到 View 中,它似乎会做不同的事情,但它不应该做同样的事情吗?

【问题讨论】:

它只是应用 CSS 属性,所以你可以看看 this question about difference between flex and flex-grow 谢谢。问题是,它与 css 不一样,对吧?在 css flex: 中,它不仅仅是反应原生的数字。对比 react native flexbox 和 css flexbox 的时候,你知道有哪些例外吗? 从未使用过 React Native,只使用过 React,而且它通常不会对 style 属性做任何神奇的事情,它只是将属性分配为 CSS 属性。但是我没有检查代码。我想比较的一个很好的基础是在 React Native 中创建一个页面和一个使用纯 CSS 的页面,两者都生成相同的标记并比较结果。 【参考方案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>;

这是上面代码的截图:

添加了widthheight

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,它应该通过设置widthheight 属性来调整大小,但如果没有设置,它似乎适合内容。 flex: 0, flexBasis: px 元素采用flexBasis给定的大小 flex: 0, flexGrow: 1 带有flex: 0flexGrow: 1;这与将内容的大小(在上面的示例中为 a )添加到设置为 flex: 1 的元素的大小相同。它与flex: 1, flexBasis: 10 类似,只是不是添加像素数量而是添加内容的大小。 flex: 0, flexShrink: 1 对于flex: 0flexShrink: 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: 0height 的处理方式与flexBasis 相同。如果同时设置了heightflexBasis,则忽略height

flex: 1

flex: 1 元素占用了可用空间。详情请见Layout Props documentation flex: 1, flexBasis: px 带有flex: 1flexBasis: pxflexBasis 的值被添加到元素的大小。换句话说,这就像取一个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: 1height 将被忽略。请改用flexBasis

以下是我的观察:

疑难解答提示:确保父视图为子视图提供了增长/缩小的空间。注意父视图上的flex: 1,没有它,所有子视图都不会按您的预期显示。 疑难解答提示:在测试这些值时不要使用Hot Reloading,它会在重新加载几次后错误地显示元素。我建议启用 Live Reload 或使用 command + r (很多)。 默认的弹性值为flex: 0。如果您不添加 flex 样式值,则默认为 0。 疑难解答提示:如果您想弄清楚为什么某些内容没有按您认为的那样显示,请从(大多数)父元素开始,并确保它为其子元素提供了足够的空间做他们需要做的事。换句话说,尝试将其设置为 flex:1 看看是否有帮助,然后转到下一个孩子并重复。 似乎width 总是与flexDirection: "column" 一起考虑,无论其他弹性道具如何。这同样适用于 heightflexDirection: "row"。 运行这些测试后,通常我会使用flexBasis 而不是height,因为flexBasis 胜过height

【讨论】:

这个答案显然缺少 react native flex 的文档。谢谢。 你是我的救命恩人...;) React Native 中 Flex 的精彩解释。非常感谢。 flex: -1 怎么样?迄今为止最好的解释。 您的“观察”部分非常有帮助,谢谢。

以上是关于React Native 中的 flex vs flexGrow vs flexShrink vs flexBasis?的主要内容,如果未能解决你的问题,请参考以下文章

FlatList vs map react-native

将 json 页面连接到 React-native 中的 flex 行

alignItems: center 防止 React Native 中的 flex 行文本换行

React Native`alignItems:'flex-end'`隐藏TabBarIOS组件中的内容

React Native 中的动画字段宽度

模拟显示:React Native 中的内联