💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、豆包、星火、月之暗面及文生图、文生视频 广告
### RN组件 * * * * * RN与React不同的是,它没有div/img/p...等组件,它有一些内置的常用组件。 #### 常用组件: * Text(显示文本的React组件,并且它也支持嵌套、样式,以及触摸处理。) * View(相当于div的职责) * Image * Button * TextInput(输入框) * ScrollView(滚动视图) * FlatList(ListView已过时)-- 列表 * Modal模态框 * TouchableHighlight * TouchableNativeFeedback * TouchableOpacity * TouchableWithoutFeedback #### 支持onPress的组件 Text、TouchableHighlight、TouchableNativeFeedback、TouchableOpacity、TouchableWithoutFeedback **Text** 显示文本的React组件,并且它也支持嵌套、样式,以及触摸处理。 ~~~ <Text numberOfLines={2} // 文本显示行数 多余... onPress={()=>{alert(1)}} // 点击事件 onLongPress={()=>{alert('longPress')}} // 长按事件 selectable={true} // 是否可以选择文本 style={{color:'red',fontFamily:'',fontSize:14,fontWeight:200,lineHeight:20,textAlign:'center'}} // 样式 > </Text> ~~~ | 嵌套 | Text标签里面可以嵌套Text标签 | | --- | --- | | 继承 | 子Text标签会且只会继承`父Text`标签的样式,除了Text外的组件将不会有文本属性 | | 容器 | Text元素不使用flex布局,采用文本布局,它将不再是一个矩形容器,文字过长时会折叠 | 注意:Text里面可以嵌套View,但是View必须设置高度宽度。 由于不能直接设置一整颗子树的默认样式。但是又有很多样式重复的Text,可以每个Text指定同一个styles,或者创建一个包含相关样式的组件MyAppText。 **View** 创建UI时最基础的组件,View是一个支持Flexbox布局、样式、一些触摸处理、和一些无障碍功能的容器,并且它可以放到其它的视图里,也可以有任意多个任意类型的子视图。相当于是web里面的div的级别。 ~~~ <View accessibilityLabel={} accessible={true} onAccessibilityTap={()=>{}} onLayout={()=>{}} onMagicTap={()=>{}} onMoveShouldSetResponder={()=>{}} ... style={} > </View> ~~~ 不能在View里面直接写文字,文字必须写在Text组件里面。平常View用到最多的就是布局,View的设计初衷是和StyleSheet搭配使用。 **Image** ~~~ // 静态图片资源 <Image source={require('./my-icon.png')} /> // 网络图片 <Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}} style={{width: 400, height: 400}} /> ~~~ 注意点: | 静态图片 | require里面不能使用变量,一定要是静态字符串 | | --- | --- | | 网络图片 | 一定要设置width和height | | 圆角边框 | borderRadius可以,但是borderTopLeftRadius,borderTopRightRadius,borderBottomLeftRadius,borderBottomRightRadius这四个属性在IOS上使用在Image组件上无效| | 背景图片 | 有时候会用到图片背景,但Rn是没有background-image属性的,我们可以使用`ImageBackground`组件 | | source是个object对象 | 未来可能会加入精灵图(sprites)的支持:在输出{uri: ...}的基础上,我们可以进一步输出裁切信息{uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}},这样理论上就可以在现有的代码中无缝支持精灵图的切分。 | **Button** ~~~ <Button title="按钮" color="#841584" // ios 文本的颜色 Android 按钮的背景色 accessibilityLabel="我会被读出来的文本" // 给残障人士显示的文本 onPress={()=>{alert("我是按钮")}} /> ~~~ 按钮颜色在IOS和Android上不统一,建议使用Touchable系列组件。 **TextInput** TextInput是一个允许用户在应用中通过键盘输入文本的基本组件。本组件的属性提供了多种特性的配置,譬如自动完成、自动大小写、占位文字,以及多种不同的键盘类型(如纯数字键盘)等等。 ~~~ <TextInput style={{height: 50,borderWidth:1,borderColor:'#ccc'}} onChange={()=>{}} // 改变值不会作为参数传递 onChangeText={(val)=>{this.setState({TextVal: val})}} autoCapitalize='sentences' // 是否要自动将特定字符切换为大写 autoCorrect={true} // 是否关闭拼写自动修正 autoFocus={true} // 在componentDidMount后会获得焦点 maxLength={10} // 最多的字符数 multiline={false} // 是否多行 onBlur={()=>{alert('失去焦点')}} onFocus={()=>{alert('获得焦点')}} placeholder='请输入' placeholderTextColor='#ccc' value='' /> <Text>{this.state.TextVal}</Text> ~~~ | onChangeText | 从TextInput里取值这就是目前唯一的做法! | | --- | --- | **ScrollView** ScrollView必须要有一个高度,或者设置`flex:1`,因为ScrollView是将一系列不确定高度的子组件装进一个确定高度的容器(通过滚动操作)。 ~~~ <ScrollView contentContainerStyle={styles.contentContainer} horizontal={true} // true 横向滚动 keyboardDismissMode='none' // 滚动时隐藏键盘 onScroll={()=>{}} // 滚动函数 refreshControl={<View></View>} // 刷新的头组件 showsHorizontalScrollIndicator={false} // 横向滚动条 > </ScrollView> ~~~ | ScrollView | ListView | FlatList | | --- | --- | --- | | 把所有子元素一次性全部渲染出来 | ListView会惰性渲染子元素,只在它们将要出现在屏幕中时开始渲染。 | 0.43版本开始新出的改进版的ListView,性能更优 | **FlatList** ~~~ <FlatList data={this.state.courseList} renderItem={this._renderCourse.bind(this)} // 循环渲染子组件 keyExtractor={(item, index) => item.courseId} // 设置唯一key值 /> ~~~ 功能: * 完全跨平台。 * 支持水平布局模式。 * 行组件显示或隐藏时可配置回调事件。 * 支持单独的头部组件。 * 支持单独的尾部组件。 * 支持自定义行间分隔线。 * 支持下拉刷新。 * 支持上拉加载。 * 支持跳转到指定行(ScrollToIndex)。 官网的一个例子: ~~~ class MyListItem extends React.PureComponent { _onPress = () => { this.props.onPressItem(this.props.id); }; render() { return ( <SomeOtherWidget {...this.props} onPress={this._onPress} /> ) } } class MyList extends React.PureComponent { state = {selected: (new Map(): Map<string, boolean>)}; _keyExtractor = (item, index) => item.id; _onPressItem = (id: string) => { // updater functions are preferred for transactional updates this.setState((state) => { // copy the map rather than modifying state. const selected = new Map(state.selected); selected.set(id, !selected.get(id)); // toggle return {selected}; }); }; _renderItem = ({item}) => ( <MyListItem id={item.id} onPressItem={this._onPressItem} selected={!!this.state.selected.get(item.id)} title={item.title} /> ); render() { return ( <FlatList data={this.props.data} extraData={this.state} keyExtractor={this._keyExtractor} renderItem={this._renderItem} /> ); } } ~~~ 优化点: | 每个item渲染的时候 | 1.onPressItem属性使用箭头函数而非bind的方式进行绑定,使其不会在每次列表重新render时生成一个新的函数,从而保证了props的不变性,不会触发自身无谓的重新render。2.如果你是用bind来绑定onPressItem,每次都会生成一个新的函数,导致props在===比较时返回false,从而触发自身的一次不必要的重新render。 | --- | --- | | 指定extraData={this.state}属性 | 保证state.selected变化时,能够正确触发FlatList的更新。如果不指定此属性,则FlatList不会触发更新,因为它是一个PureComponent,其props在===比较中没有变化则不会触发更新。PureComponent仅仅是浅比较,即使对象内容改变了,它指向的还是同一个对象。 | | keyExtractor | 指定使用id作为列表每一项的key | PureComponent的shouldComponentUpdate: ~~~ if (this._compositeType === CompositeTypes.PureClass) { shouldUpdate = !shallowEqual(prevProps, nextProps) || ! shallowEqual(inst.state, nextState); // 浅比较 } ~~~ [PureComponent的重要性和使用方式](http://www.zcfy.cc/article/why-and-how-to-use-purecomponent-in-react-js-60devs-2344.html) **组件推荐:** * [react-navigation](https://github.com/react-community/react-navigation) FB推荐导航组件 * [react-native-tab-navigator](https://github.com/happypancake/react-native-tab-navigator) Tab切换 * [react-native-scrollable-tab-view](https://github.com/skv-headless/react-native-scrollable-tab-view) Tab切换,每个tab有自己的ScrollView,可自定义tab样式 * [react-native-easy-toast](https://github.com/crazycodeboy/react-native-easy-toast) * [react-native-image-picker](https://github.com/react-community/react-native-image-picker) 本地图片选择 * [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons) 字体图标 * [react-native-swiper](https://github.com/leecade/react-native-swiper) 轮播图 * [react-native-storage](https://github.com/sunnylqm/react-native-storage) 基于AsyncStorage的本地存储 **组件封装:**