首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

RN学习文档

2024-12-20 来源:化拓教育网

一、React Native配置环境

  1. React Native中文网:
  2. React Native环境配置(简书):

二、引入第三方库 / 组件

第三方库引入

npm install name(三方库名) --save 安装的同时,将信息写入package.json中

组件引入(自定义组件)

import TextInputView from '../../components/EF_TextInputView'

三、setState渲染问题

    constructor(props) {
        super(props);
        this.state = {
            isLoading: true, // 下拉刷新数据标记
        };
    }
    _this.setState({
          isLoading: false,
   })

四、页面传值问题

1.直接传值

例如下侧代码中的 albumId= {this.props.albumId},=前面表示参数名,后面表示要传的数据。

<AlertCell
     modalVisible={this.state.modalVisible}
     navigator={this.props.navigator}
     coverType= {this.props.coverType}
     headerPhoto= {this.props.headerPhoto}
     albumId= {this.props.albumId}
     photosArr={photosArr}
     dataArr={dataArr}
     albumTitle={this.props.title1}
     albumDesc={this.props.albumDesc}
     {...this.props}
           onClose={() => {
                this.setState({modalVisible: false})
}}/>
2.跳转页面传值

使用Navigator进行页面跳转,进行传值时,

Navigator的使用

    /*
     * 设置Navigator转场方式
     * */
    configureScene = (route, routeStack) => {
        if (route.type == 'bottom') {
            return Navigator.SceneConfigs.FloatFromBottom; // 底部弹出
        } else if (route.type == 'fade') {
            return Navigator.SceneConfigs.FadeAndroid; // 淡入淡出
        }
        return Navigator.SceneConfigs.PushFromRight; // 右侧弹出
    };

    /*
     * 传值
     * */
    renderScene = (route, navigator) => {
        return  navigator={navigator}  {...route.passProps} />;//传值(使用时参数名passProps要与这里统一)
    };

    render() {
        return (
            <View style={{flex: 1}}>
                <Navigator
                    style={{flex: 1}}
                    initialRoute={{component: Main}}//初始界面
                    configureScene={this.configureScene}
                    renderScene={this.renderScene}/>
                {/*加载全局的顶部提示框组件*/}
                <TopAlertBox />
            </View>
        )
    }

传值

   var navigator = this.props.navigator;
   navigator.push({
        title: '',
        component: CreateAlbumView,
        passProps: {
             title1: '新建相册',
             navigator: navigator,
             data: this.data,
        },
        type: 'bottom'
    })
3.反向传值

界面一:

   var navigator = this.props.navigator;
   navigator.push({
        title: '新建相册',
        component: CreateAlbumView,
        passProps: {
             title1: '',
             navigator: navigator,
             // 反向传值
             getAlbum: function(albumData) {
                 albumArr.push(albumData);
                 _this.setState({
                       dataSource: ds.cloneWithRows(albumArr),
                 })
             }
        },
        type: 'bottom'
    })

界面二:

    _this.props.getAlbum(albumData);
         if (_this.props.navigator) {
               _this.props.navigator.pop();
   }
4.通知传值

引入RCTDeviceEventEmitter

import RCTDeviceEventEmitter from 'RCTDeviceEventEmitter'

设置监听

    componentDidMount() {
        let me = this;
        // 删除相册
        this.delete_listener = RCTDeviceEventEmitter.addListener('删除相册',         function(albumId) {
            for (let i = 0; i < albumArr.length; i++) {
                if (albumArr[i].id === albumId) {
                    albumArr.splice(i, 1);
                }
            }
            me.setState({
                dataSource: ds.cloneWithRows(albumArr),
            })
        });
        // 编辑相册
        this.edit_listener = RCTDeviceEventEmitter.addListener('编辑相册', function(albumId, params) {
            for (let i = 0; i < albumArr.length; i++) {
                if (albumArr[i].id === albumId) {
                    albumArr[i].albumTitle = params.albumtitle;
                    albumArr[i].coverType = 1;
                    albumArr[i].albumCover = params.albumcover;
                }
            }
            me.setState({
                dataSource: ds.cloneWithRows(albumArr),
            })
        });
    }
    componentWillUnmount() {
        this.delete_listener.remove();
        this.edit_listener.remove();
    }

发通知

 RCTDeviceEventEmitter.emit('编辑相册', _this.state.albumId, params);

五、封装数据请求

     /*
     *  post请求发送说说
     *  params:参数
     *  callback:回调函数
     * */
    static postShortposts(params, callback) {
        url = API + 'shortposts/';
        let paramsStr = '';

        console.log('参数:' + JSON.stringify(params));
        if (params) {
            let paramsArray = [];
            //拼接参数
            Object.keys(params).forEach(key => paramsArray.push(key + '=' + params[key]))
            paramsStr += paramsArray.join('&');
        }

        console.log('url:  ' + url);
        console.log('body:  ' + paramsStr);
        //fetch请求
        fetch(url, {
            method: 'POST',
            headers: {
                'Content-Type': 
            },
            body: paramsStr,
        })
            .then((response) => response.json())
            .then((responseJSON) => {
                callback(responseJSON)
            }).done();
    }

六、flex布局

七、this指向问题

this在RN中就是指这个类本身,但是经常会报一些错误:not an object(this.)或者not a funcation等,这类问题一般有两种解决办法

1.在render中里面调用方法的时候,使用this.方法名.bind(this),重新绑定一下this

2.在方法里面, let _this = this,使用_this来调用本身类

八、性能优化问题

1、声明方法函数时,要尽量使用 方法名= ()=> {},这样会减少方法引用的次数。然后在调用的时候,直接使用this.方法名即可。

2、只有 shouldComponentUpdate 返回true的时候才会更新页面。。比较this.props的isClicked属性(属性看自己情况而定)与newProps的isClicked属性是否相同。

shouldComponentUpdate(newProps, newState){
        if(swllowArrayCompare(this.props.isClicked, newProps.isClicked)){
                renturn  true;
        }
        return false;
   }

3、使用属性的时候,如果不需要重新渲染的属性,直接在state外面声明即可,调用的时候 this.属性名,这样就不会调用render函数了,不会重新渲染界面。

4、在render中使用const {属性}= this.prps,直接使用属性名就可以调用。这样可以不用再state里面使用了,减少了渲染的次数。

5、推迟render的过程,在数据请求完之后,使用InteractionManager.runAfterInteractions( ()=> {this.setStates({})})

6、使用mbox,只改变需要改变的,不重新全部渲染。

显示全文