1import React from 'react'; 2import { Platform, StyleSheet, Text } from 'react-native'; 3 4function useChildren(inputChildren: React.ReactNode) { 5 return React.useMemo(() => { 6 const children: React.ReactNode[] = []; 7 React.Children.forEach(inputChildren, (child) => { 8 if (child == null || typeof child === 'boolean') { 9 } else if (typeof child === 'string' || typeof child === 'number') { 10 // Wrap text in a Text component. 11 let message = `Invalid raw text as a child of View: "${child}"${ 12 child === '' ? ` [empty string]` : '' 13 }.`; 14 message += ' Wrap the text contents with a Text element or remove it.'; 15 console.warn(message); 16 children.push( 17 <Text style={[StyleSheet.absoluteFill, styles.error]}> 18 Unwrapped text: "<Text style={{ fontWeight: 'bold' }}>{child}</Text>" 19 </Text> 20 ); 21 } else if ('type' in child && typeof child?.type === 'string' && Platform.OS !== 'web') { 22 // Disallow untransformed react-dom elements on native. 23 throw new Error(`Using unsupported React DOM element: <${child.type} />`); 24 } else { 25 children.push(child); 26 } 27 }); 28 return children; 29 }, [inputChildren]); 30} 31 32/** Extend a view with a `children` filter that asserts more helpful warnings/errors. */ 33export function createDevView<TView extends React.ComponentType<any>>(View: TView) { 34 return React.forwardRef(({ children, ...props }: any, forwardedRef: React.Ref<TView>) => { 35 return <View ref={forwardedRef} {...props} children={useChildren(children)} />; 36 }); 37} 38 39const styles = StyleSheet.create({ 40 error: { 41 backgroundColor: 'firebrick', 42 color: 'white', 43 }, 44}); 45