0

我在 TypeScript SafeAreaView组件中遇到了一个奇怪的错误。我为 WebView 创建了其他参考并且它没有失败,只是在分配给 SafeAreaView 组件时似乎失败了。

import { useRef, MutableRefObject } from 'react';
import { SafeAreaView } from 'react-native-safe-area-context';
...
...
const topSafeAreaViewRef = useRef(null);
...
...
<SafeAreaView ref={topSafeAreaViewRef} style={styles.container} edges={['top', 'right', 'left']} >

TS2322:类型'{孩子:元素;参考:可变参考对象;风格:{弹性:数字;背景颜色:任意;}; 边缘:(“顶部”|“右”|“左”)[];}' 不可分配给类型 'IntrinsicAttributes & ViewProps & { children?: ReactNode; 模式?:“填充”| “边距” | 不明确的; 边缘?:只读边缘 [] | 不明确的; }'。类型'IntrinsicAttributes & ViewProps & { children?: ReactNode; 上不存在属性'ref' 模式?:“填充”| “边距” | 不明确的; 边缘?:只读边缘 [] | 不明确的; }'。

我需要 ref 因为我需要在外部函数上设置setNativeProps

const handleOnLoadEnd = (
    syntheticEvent: WebViewNavigationEvent | WebViewErrorEvent,
    topSafeAreaViewRef: MutableRefObject<any>,
) => {
  topSafeAreaViewRef.current.setNativeProps({
    style:{
      backgroundColor: Constants?.manifest?.extra?.webViewBackground,
    }
  });

};
4

3 回答 3

2

的组件不支持react-native-safe-area-context道具。SafeAreaViewref

如果您需要ref计算宽度、高度等,您可以尝试这样的解决方法(未经测试):

import { useRef } from 'react';
import { View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

function App() {
  const ref = useRef();
  const insets = useSafeAreaInsets();

  return (
    <View
      ref={ref}
      style={{
        paddingTop: insets.top,
        paddingLeft: insets.left,
        paddingBottom: insets.bottom,
        paddingRight: insets.right,
      }}
    />
  );
}
于 2022-01-25T12:54:26.393 回答
0

在我的实验中,它似乎ref确实有效。将其所有道具传递给底层组件。但它不使用,所以它似乎不应该工作。SafeAreaViewViewforwardRef

Expo Snack - 加载后背景将变为红色WebView(在 iOS 上)。

如果它符合您的要求并且只是一个 TypeScript 错误,您可以随时使用// @ts-ignore. 这不是一个理想的解决方案,但它可能是最简单的。


我需要 ref 因为我需要设置setNativeProps一个外部函数

我建议尝试构建您的组件,以便您可以通过道具控制样式并且不需要使用 refs 或setNativeProps. 我不确定 yourWebView和 your之间的关系SafeAreaView,但请尝试以下操作:

interface ComponentWithWebViewProps {
  setStyle: (style: ViewStyle) => void;
}

const ComponentWithWebView = ({ setStyle }: ComponentWithWebViewProps) => {
  return (
    <WebView
      source={{
        uri: 'https://stackoverflow.com/questions/70848728/safeareaview-ref-generates-a-typescript-error/',
      }}
      onLoadEnd={() =>
        setStyle({
          backgroundColor: 'red',
        })
      }
      style={{ flex: 1 }}
    />
  );
};

const ParentComponent = () => {
  // These are the extra/override styles that we are adding.
  const [customStyle, setCustomStyle] = React.useState<ViewStyle>({});
  return (
    <SafeAreaView
      // Can pass multiple styles in an array
      style={[styles.container, customStyle]}
      edges={['top', 'right', 'left']}>
      <Text>Hello, World</Text>
      <ComponentWithWebView setStyle={setCustomStyle} />
    </SafeAreaView>
  );
};

export default function App() {
  return (
    <SafeAreaProvider>
      <ParentComponent />
    </SafeAreaProvider>
  );
}

世博小吃

于 2022-02-05T20:48:45.633 回答
0

SafeAreaView是使用插图的首选方式。这是一个常规View,插入作为额外的填充或边距。它通过原生应用插图来提供更好的性能,并避免其他基于 JS 的消费者可能发生的闪烁。

SafeAreaView是一个常规的 View 组件,其安全区域插图应用为填充或边距。

内边距或边距样式被添加到插图中,例如style={{paddingTop: 10}}在具有 20 插图的SafeAreaView上将导致顶部内边距为 30。

例子:

import { SafeAreaView } from 'react-native-safe-area-context';

function SomeComponent() {
  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: 'red' }}>
      <View style={{ flex: 1, backgroundColor: 'blue' }} />
    </SafeAreaView>
  );
}

边缘:

可选,顶部、右侧、底部和左侧的数组。默认为所有。

设置要应用安全区域插图的边缘。

例如,如果您不希望插入应用到顶部边缘,因为视图不接触屏幕顶部,您可以使用:

<SafeAreaView edges={['right', 'bottom', 'left']} />

有关更多详细信息或文档,您可以在此处查看

您应该删除useRef(),因为 useRef 在 SafeAreaView 中没有运动。

于 2022-01-25T12:53:15.680 回答