如何确保 react-native 中的 flex 收缩(以及一般情况下如何调试 react-native 样式)?

How can you ensure flex shrink in react-native (and how can you debug react-native styles in general)?

我是 运行 一个使用 native-base 样式的 RN 应用程序。我的主页上有四个元素:一个 header,一个来自 vreact-native-tab-view 的选项卡视图,其中包含一个 ScrollView,它占据了大约 70% 的视口,还有两个较小的 100% width 元素在底部。

但是,滚动视图占满了 100% 以上的视口,两个较小的元素被推到了底部。

我查看了我的元素检查器,可以将 flexShrink 应用于许多 div 中的一些,但我不确定我的代码中是哪一个,因为它是 div 地狱你使用 react-native。 React devtools 也有同样的问题,除了它是 View hell.

那么,两个问题:

  1. 如何确保滚动容器不会在页面上填满它应该填满的内容?
  2. 当 chrome 和 React 开发工具都一团糟时,我如何有效地调试 React Native?

作为参考,这是我到目前为止的样式:

Home.tsx:

<View flex={1}> // applied a flex for the entire homepage
  <TabView
    navigationState={{ index, routes }}
    renderScene={renderScene}
    renderTabBar={renderTabBar}
    onIndexChange={setIndex}
    initialLayout={{ width: layout.width, height: "100%" }}
  />

  <View width="100%">
    <Center width="100%">
      <StrengthSlider />
    </Center>
    <AdMobBanner
      ...props
    />
  </View>
</View>

Teas.tsx:

<View flex={1} bg="white">
  <ScrollCards teas={blackTeas} />
</View>

ScrollCards.tsx:

<ScrollView>
  <Center>
    {teas.length > 0 &&
      teas.map((teaObj) => (
        <TeaCard id={teaObj.id} teaData={teaObj.data} key={teaObj.id} />
      ))}
  </Center>
</ScrollView>

编辑:

代码沙箱link:https://codesandbox.io/s/gracious-sammet-l4tqz?file=/src/App.js&resolutionWidth=402&resolutionHeight=675

请注意,admob 页脚保留在卡片内容下方。它应该是粘性的并且始终保持在屏幕底部。我还注意到,当我不使用 MainStackNavigator 中的 header 时,页脚按预期工作 - 即它在底部保持粘性 - 但我不明白为什么使用 header (AppBar) 组件应该会干扰我的页脚。

试试这个 - https://snack.expo.dev/fL0OgQ9uS

import React from 'react';
import { View, Image, StyleSheet,ScrollView,Text } from 'react-native';

const styles = StyleSheet.create({
  container: {
    paddingTop: 50,
    flex:1,
    backgroundColor:'aqua',
  },
  tinyLogo: {
    width: 200,
    height: 200,
  },
  header:{
    backgroundColor:'green',
    paddingBottom:20,
  },
  footer:{
    backgroundColor:'green',
    paddingTop:20,
  }
});

const DisplayAnImage = () => {
  return (

    <View style={styles.container}>
      <View style={styles.header}><Text>header</Text></View>
       <ScrollView>
        <Image
        style={styles.tinyLogo}
        source={require('@expo/snack-static/react-native-logo.png')}
      />
              <Image
        style={styles.tinyLogo}
        source={require('@expo/snack-static/react-native-logo.png')}
      />
              <Image
        style={styles.tinyLogo}
        source={require('@expo/snack-static/react-native-logo.png')}
      />
              <Image
        style={styles.tinyLogo}
        source={require('@expo/snack-static/react-native-logo.png')}
      />
              <Image
        style={styles.tinyLogo}
        source={require('@expo/snack-static/react-native-logo.png')}
      />
              <Image
        style={styles.tinyLogo}
        source={require('@expo/snack-static/react-native-logo.png')}
      />

              <Image
        style={styles.tinyLogo}
        source={require('@expo/snack-static/react-native-logo.png')}
      />
  
      </ScrollView>
      <View  style={styles.footer}><Text>footer</Text></View>
    </View>

  );
}

export default DisplayAnImage;

你可以尝试更换

<View flex={1}> // applied a flex for the entire homepage

Home.tsx

<View flex="1 1 0">

工作示例here(您的代码是否修改了该行)。

至于调试,我只能建议 react native Debugging page. Have you tried React Developer Tools yet? In chrome you can also add it as an extension from this link.

上已经建议的内容

我不确定 chrome 扩展和 npm 包之间是否有任何区别,但至少(目前)扩展对我来说已经足够了。

唯一的问题是我在 codesandbox 上也很难调试,因为扩展肯定不能在 javascript 在线编辑器上工作(但 npm 包可能不适用于这种特定情况)

获得所需结果的正确解决方案是将 flexBasis 添加到 TabView,例如:

<TabView 
  style={{ flexBasis: 0 }}
  // rest of the code
/> ​

为什么? TabView 的默认样式为 flex: 1, overflow: 'hidden'(参见 source code),导致它扩展到其最大子项的大小。 flexBasis 防止这种情况并确保 tabview 获得正确的高度。

资源:这是一篇关于 flexBasis 与 width/height 的精彩文章:https://mastery.games/post/the-difference-between-width-and-flex-basis/


在 React-Native 中调试样式并没有最好的开发者体验。您可以使用一些工具来帮助您调试样式:

  • RN inspector:正如 Berci 提到的,React native 有一个开发菜单,您可以在其中 select“显示检查器”,其作用类似于浏览器中的“检查元素”。它是调试您可以看到的元素的好工具,它还有助于调试 input/tab 事件。

  • 颜色:大多数情况下,我只是使用老式的彩色边框和背景来清楚地了解元素的位置及其 size/overlaps。

  • 注释和简化:随意注释掉您不感兴趣的组件,并用简单的彩色视图替换复杂的 components/views,例如 ScrollCards。这有助于防止多种行为影响您尝试调试的内容

  • 浏览器检查和 React 开发工具:如果您碰巧 运行 在浏览器中使用您的 RN 应用程序,那么熟悉这些工具将有助于您加载。请记住,React 和 React-Native 是不一样的。

当您调试视觉效果时,最好的方法是从顶层开始,然后一直向下。为元素着色并随意注释掉元素,让您更清楚地了解问题。继续深入挖掘,直到找到问题,不要害怕查看你使用的包的源代码,它通常有助于澄清(意外的)行为。