初識ReactNative

公司打算用react-native開發(fā)APP匆帚,初始RN遇到了很多坑谴咸,搭建了一個小的項目框架,結(jié)合redux根據(jù)公司現(xiàn)成的接口寫了幾個小demo卷谈,接觸前端半年多杯拐,之前是做iOS的,感覺轉(zhuǎn)起來很困難世蔗,希望有大神可以給出些優(yōu)化的建議端逼!

項目介紹

  • 這是一個利用react-native配合redux開發(fā)的小框架。
  • 項目主要結(jié)構(gòu)
  • android 安卓原生代碼
  • ios iOS原生代碼
  • src RN代碼
    • actions 處理事件污淋,是把數(shù)據(jù)從應(yīng)用(譯者注:這里之所以不叫 view 是因為這些數(shù)據(jù)有可能是服務(wù)器響應(yīng)顶滩,用戶輸入或其它非 view 的數(shù)據(jù) )傳到 store 的有效載荷。它是 store 數(shù)據(jù)的唯一來源芙沥。
    • components 子組件
    • constants 常量诲祸,actions中用到的狀態(tài),action 內(nèi)必須使用一個字符串類型的 type 字段來表示將要執(zhí)行的動作而昨。多數(shù)情況下救氯,type 會被定義成字符串常量。當(dāng)應(yīng)用規(guī)模越來越大時歌憨,建議使用單獨的模塊或文件來存放 action着憨。
    • containers 父組件,類似于MVC中的控制器务嫡,
    • reducers 改變狀態(tài)甲抖,action描述事件發(fā)生,通過reducers改變狀態(tài)state
    • statics資源(例如圖片)
    • utils工具方法
    • store統(tǒng)一管理狀態(tài)
    • index.htmlhtml加載DOM
    • root.jsRN入口
  • index.android.js 安卓程序的入口
  • index.ios.js 蘋果程序入口
  • package.json 配置文件

項目啟動流程

  • index.html通過加載<div id="react-root"></div>進(jìn)入root.js
<!DOCTYPE html>
<meta charset="utf-8">
<title>React Native for Web</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<div id="react-root"></div>
<script src="/bundle.js"></script>
  • root.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import App from './containers/App';
import configureStore from './store/configureStore';
class Root extends Component {
  render() {
    return (
      <Provider store={configureStore()}>
        <App />
      </Provider>
    );
  }
}
export default Root;
  • App.js設(shè)置一些啟動時需要做的事情心铃,renderScene添加路由
import React, {Component} from 'react';
import { Navigator } from 'react-native';
import MainTabsView from './MainTabsView';
import BroswerView from './BroswerView';
import LoginView from './LoginView';
import CarDetailView from './CarDetailView'
import FindCarView from './FindCarView'
import FreePriceView from './FreePriceView'
import CarLifeView from './CarLifeView'
import SpecialCarView from './SpecialCarView'
const ROUTES = {
  main_tabs_view: MainTabsView,
  login_view:LoginView,
  broswer_view: BroswerView,
  car_detail_view:CarDetailView,
  find_car_view:FindCarView,
  free_price_view:FreePriceView,
  car_life_view:CarLifeView,
  special_car_view:SpecialCarView,
}
class App extends Component {
  renderScene = (route, navigator) => {
    let Scene = ROUTES[route.name];
    console.log("app renderscene");
    switch (route.name){
      case 'main_tabs_view':
        return <Scene navigator={navigator} tab={2}/>;
      case 'login_view':
        return <Scene navigator={navigator}/>;
      case 'broswer_view':
        return <Scene
          url={route.url}
          navigator={navigator}/>;
      case 'car_detail_view':
        return <Scene {...route.params} navigator={navigator}/>;
      case 'find_car_view':
        return <Scene navigator={navigator}/>;
      case 'free_price_view':
      return <Scene navigator={navigator}/>;
      case 'car_life_view':
        return <Scene navigator={navigator}/>;
      case 'special_car_view':
        return <Scene navigator={navigator}/>;
    }
  }
  configureScene = (route, routeStack) => {
    switch (route.name){
      default:
            return Navigator.SceneConfigs.PushFromRight;
    }
  }
  render() {
    return <Navigator
      initialRoute={{name: 'login_view'}}
      renderScene={this.renderScene}
      configureScene={this.configureScene}/>
  }
}
export default App;

效果展示

  • 登錄


    登錄
  • 首頁 (redux數(shù)據(jù)流程的簡單介紹)
  • 我們在組件生命周期componentDidMount()中進(jìn)行數(shù)據(jù)請求准谚。this.props.actions.getBannerSource({});根據(jù)reduxaction中處理事件。
componentDidMount() {
    this.props.actions.getBannerSource({});
    this.props.actions.getHotCarSource({});
    this.props.actions.getFreePriceListSource({});
    this.props.actions.getCarShowBannerSource({});
    this.props.actions.getSpecialCarSource({});
  }
  • 此時數(shù)據(jù)流將會來到action中,根據(jù)狀態(tài)常量DATA_BANNER去扣,處理事件柱衔,action中只處理事件,要想改變狀態(tài),通過receiveBannerPosts(banner, json)方法去reducers中改變狀態(tài)
//輪播圖
export function getBannerSource(item) {
    console.log("getBannerSource");
    return dispatch => {

        //dispatch(requestPosts(item));
        return fetch(API_BASE_URL+'/mobile/ad/findAllShowAdByMobile', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'sessionid': "hanwuqia"
            },
            body: JSON.stringify({"query":{"pagenum":10,"page":1}})
        })
            .then((response) => response.json())
            .then((responseJson) => {
                //console.log(responseJson);
                if(responseJson.code == 0){
                    dispatch(receiveBannerPosts(responseJson.data.rows));
                }

            })
            .catch((error) => {
                console.error(error);
            });
    }
}
function receiveBannerPosts(banner, json) {
    return {
        type: DATA_BANNER,
        banner,
    }
}
  • 當(dāng)數(shù)據(jù)流來到reducer時會通過剛才的狀態(tài)常量給狀態(tài)banner賦值唆铐,這樣請求下來的數(shù)據(jù)進(jìn)入到狀態(tài)樹中哲戚。
export default function secondView(state ={
    banner: [],
}, action) {
    switch (action.type) {
        case types.DATA_BANNER :
            return Object.assign({}, state, {
                banner: action.banner
            });
        default:
            return state
    }
}
  • 這時在組件中得知狀態(tài)改變從而重修刷新render方法,填充數(shù)據(jù),這樣就獲得了輪播圖的數(shù)據(jù)艾岂,這里輪播圖我用了一個叫做react-native-viewpager 的第三方組件
function mapStateToProps(state) {
  return {
    banner: state.secondView.banner,
  };
}
function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(Actions, dispatch)
  }
}
export default connect(
    mapStateToProps,
    mapDispatchToProps
)(SecondView);
  • RN 中所有布局全部包在一個大的View中就好像h5中的盒子布局的div類似顺少,如果有兩個大盒子會報錯const { } = this.props;是es6語法獲得到這個組件的狀態(tài),通過這樣的方法<Banner banner={banner}></Banner>傳給子組件王浴,每當(dāng)狀態(tài)改變時會自動刷新脆炎,進(jìn)而子組件內(nèi)容也進(jìn)行刷新。
render() {
    const {  banner ,hotCarList,freePriceList,carShowBanner,specialCar,navigator} = this.props;
    return (
        <View style={{ flex: 1, backgroundColor:'#EBEBEB'}}>
            <TitleBar title="react-native-mobile"></TitleBar>
            <ScrollView >
                <Banner banner={banner}></Banner>
                <ToolBar navigator={navigator}></ToolBar>
                <Text style={styles.title}>免費看低價</Text>
                <FreePriceList  navigator={navigator} freePriceList={freePriceList}></FreePriceList>
                <Text style={styles.title}>車主秀</Text>
                <CarShowBanner carShowBanner={carShowBanner}></CarShowBanner>
                <Text style={styles.title}>熱門推薦</Text>
                <HotCarList hotCarList={hotCarList} navigator={navigator}></HotCarList>
            </ScrollView>
        </View>
    )
  }
首頁

首頁
  • 找車模塊
  • 找車的熱門選車模塊用到了RN中核心組件ListView的使用,這是一個分組的listView, dataSource就是列表的數(shù)據(jù)源氓辣,根據(jù)官方文檔不同樣式的列表有不同的初始化傳參方式腕窥,這里只介紹分組的列表,項目中用到了很多各種各樣的listView列表筛婉!所以說他是核心組件。renderRow返回每行樣式癞松,renderSectionHeader返回每組組頭爽撒,renderHeader返回列表表頭,像我一樣做過iOS開發(fā)的朋友可能會覺得不得理解响蓉,就像我們的UITableView中的各種代理方法一樣硕勿,官網(wǎng)還有很多,很實用枫甲。
render(){
        const { brand} = this.props;
        var  Arr = brand ,
            sectionIDs =[],//所有區(qū)ID的數(shù)組
            rowIDs =[];//行ID數(shù)組
        for (let i in brand ) {
            sectionIDs.push(i);
            rowIDs.push(brand[i])
        }
        return(
                <ListView//創(chuàng)建表源武,并設(shè)置返回section和cell的方法
                    dataSource={this.dataSource.cloneWithRowsAndSections(Arr,sectionIDs,rowIDs)}
                    renderRow={this.renderRow}
                    renderSectionHeader={this.renderSectionHeader}
                    renderHeader={this.renderHeader }
                />
        )
    }
//返回頭部視圖
    renderHeader(){
        var rowWidth = screenWidth/5;
        return(
            <View  style={{width:screenWidth,flexDirection:'row',flexWrap:'wrap',height:160}}>
                {
                    this.hotBrndArr.map((dic, i) => <TouchableOpacity key={i} style={{width:rowWidth,height:80}} onPress={() => {
                                    this.selectBrand(dic)}}>
                        <View  style={{backgroundColor:'white',justifyContent:'center',alignItems:'center',width:rowWidth,height:80}}>
                            <Image style={styles.imageStyle} source={{ uri: dic[1]}}/>
                            <Text>{dic[2]}</Text>
                        </View>
                    </TouchableOpacity>)  // 單行箭頭函數(shù)無需寫return
                }
            </View>
        )
    }
    //返回cell的方法
    renderRow(rowData,sectionID,rowID,highlighRow){
        return(
            <TouchableOpacity key={rowID} onPress={() => {
                                    this.selectBrand(rowID)}}>
                <View style={styles.cellStyle}>
                    <Image style={styles.imageStyle} source={{ uri: rowID[2]}}/>
                    <Text style={{marginLeft:20}}>{rowID[1]}</Text>
                </View>
            </TouchableOpacity>

        )
    }

    //返回section的方法
    renderSectionHeader(sectionData,sectionID){

        return(
            <View style={styles.sectionStyle}>
                <Text style={{marginLeft:10}}>{sectionID}</Text>
            </View>
        )
    }
找車
  • 篩選的時候有個一個點擊側(cè)滑彈出的功能,這是糾結(jié)我最久的一塊想幻,一開始我選擇使用了官方API中的Animated粱栖,動畫實現(xiàn)方式很簡單,但是動畫加上大量的數(shù)據(jù)請求脏毯,大量的UI操作闹究,導(dǎo)致程序在安卓機(jī)上卡的一逼,畢竟只有半年前端經(jīng)驗食店,js更是菜的自己都不想說渣淤,谷歌了好幾天,安卓機(jī)的性能優(yōu)化的總是不理想吉嫩,沒辦法价认,只能采用第三方組件react-native-drawer。使用后再無性能問題自娩。
<Drawer
                    side="right"
                    type="overlay"
                    ref={(ref) => this._drawer = ref}
                    content={...}
                    tapToClose={true}
                    openDrawerOffset={0.2}
                    tweenHandler={(ratio) => ({main: { opacity:(2-ratio)/2 }})}
                    onClose={()=>{this.maskDidClose()}}
                    styles={{
                            drawer: { shadowColor: '#000000', shadowOpacity: 0.5, shadowRadius: 3},
                            main: {backgroundColor:"#EBEBEB"},
                    }}
                >
  • react-native-drawer文檔中給出了各種方向用踩,各種樣子的側(cè)滑,感覺非常好用,下面是代碼滑進(jìn)滑出的方法
closeControlPanel = () => {
        this._drawer.close()
    };
    openControlPanel = () => {
        this._drawer.open()
    };
找車篩選
  • 免費看低價
  • 這個模塊中讓我也遇到了很多的困難,首先類似UICollectionView中的布局其實也是個listView,通過設(shè)置contentContainerStyle讓他變成方形向下平鋪捶箱,運行時總是報警告說我的組頭是空的智什,然后enableEmptySections = {true}設(shè)置這個屬性解決,最蛋疼的是有時候數(shù)據(jù)雖然請求下來但是現(xiàn)實空白頁丁屎,用手碰一下就會現(xiàn)實數(shù)據(jù)荠锭,通過設(shè)置這個屬性來解決removeClippedSubviews={false}
render(){

        const { car,isRefreshing} = this.props;

        return(
            <ListView //創(chuàng)建ListView
                dataSource={this.dataSource.cloneWithRows(car)} //設(shè)置數(shù)據(jù)源
                renderRow={this.renderRow} //設(shè)置cell
                contentContainerStyle={styles.listViewStyle}//設(shè)置cell的樣式
                onEndReached={ this._toEnd }
                onEndReachedThreshold={10}
                renderFooter={ this._renderFooter }
                enableEmptySections = {true}
                removeClippedSubviews={false}
                refreshControl={
                        <RefreshControl
                            refreshing={isRefreshing}
                            onRefresh={this._onRefresh}
                            tintColor="gray"
                            title="Loading..."
                            titleColor="gray"
                            colors={['#ff0000', '#00ff00', '#0000ff']}
                            progressBackgroundColor="#ffff00"
                        />}
            />)
    }
  • 這個是RN自帶的下拉刷新,通過設(shè)置title,colors等設(shè)置下拉刷新的樣子晨川,通過設(shè)置refreshing這個bool屬性來控制刷新開始結(jié)束
refreshControl={
                        <RefreshControl
                            refreshing={isRefreshing}
                            onRefresh={this._onRefresh}
                            tintColor="gray"
                            title="Loading..."
                            titleColor="gray"
                            colors={['#ff0000', '#00ff00', '#0000ff']}
                            progressBackgroundColor="#ffff00"
                        />}
  • 當(dāng)你發(fā)現(xiàn)你的cell點擊事件無效果時证九,或者你的下拉刷新的方法沒有走,是因為你賦給ListView的方法需要聲明一下共虑,這樣才能進(jìn)入到點擊事件中如:
constructor(props) {
        super(props);
        //返回cell樣式的方法
        this.renderRow = this.renderRow.bind(this);
        //下拉刷新的方法
        this._onRefresh = this._onRefresh.bind(this);
        //上滑刷新的方法
        this._toEnd = this._toEnd.bind(this);
        //返回底部視圖的方法
        this._renderFooter = this._renderFooter.bind(this);
      //數(shù)據(jù)源初始化
        this.dataSource = new ListView.DataSource({
            rowHasChanged: (row1, row2) => row1 !== row2
        });
    }
免費看低價

免費看低價篩選
  • 車生活
  • 這個模塊是我們很常用的一個架構(gòu)愧怜,類似與網(wǎng)易新聞架構(gòu),是APP開發(fā)中非常常見的的一中架構(gòu)妈拌,首先當(dāng)然我還是嘗試著自己寫拥坛,根據(jù)按鈕點解設(shè)置scrollViewcontentOffset,根據(jù)contentOffset設(shè)置應(yīng)該選中的按鈕尘分。以及根據(jù)切換設(shè)置橙色view線的滑動猜惋,結(jié)果遇到了兩個問題,一個是向上面那樣培愁,大量數(shù)據(jù)加載著摔,大量的UI創(chuàng)建導(dǎo)致界面卡頓非常厲害,當(dāng)然是在安卓機(jī)上定续,我大蘋果肯定沒有這個問題谍咆,還有一個就是有些方法只有iOS可以試用,想寫一個兩端通用的更是難上加難,所以我引入了react-native-scrollable-tab-view這個第三方組件
render(){
        const {data,refresh,actions}=this.props;

        return(

            <ScrollableTabView  style = {{width:screenWidth,height:screenHeight-64,backgroundColor:'#EBEBEB'}}
                                initialPage={0}
                                tabBarTextStyle={{fontSize: 14}}
                                tabBarUnderlineStyle={{backgroundColor: 'orange'}}
                                tabBarInactiveTextColor = "#999999" tabBarBackgroundColor = "white" tabBarActiveTextColor = "#333333"
                                onChangeTab={(obj) => this.changeTab(obj)}
            >
                <CarLifeList tabLabel='全部' actions={actions} pid={2} index={0} refresh ={refresh} dataArr={data}></CarLifeList>
                <CarLifeList tabLabel='新車' actions={actions} pid={2} index={1} refresh ={refresh} dataArr={data}></CarLifeList>
                <CarLifeList tabLabel='裝飾' actions={actions} pid={2} index={2} refresh ={refresh} dataArr={data}></CarLifeList>
                <CarLifeList tabLabel='改裝' actions={actions} pid={2} index={3} refresh ={refresh} dataArr={data}></CarLifeList>
                <CarLifeList tabLabel='自駕' actions={actions} pid={2} index={4} refresh ={refresh} dataArr={data}></CarLifeList>

            </ScrollableTabView>
        )
           
    }
  • 在這個界面我還遇到了一個我至今還無法相同的問題,我用redux管理狀態(tài)奶躯,我把一個數(shù)組的數(shù)據(jù)當(dāng)成一個狀態(tài),每次請求數(shù)據(jù)的時候?qū)?shù)組進(jìn)行操作港粱,上滑的時候向數(shù)組中添加數(shù)據(jù),我認(rèn)為數(shù)組中數(shù)據(jù)增加了就是狀態(tài)改變了旦签,render理應(yīng)重新渲染才對查坪,但是顯然不是這樣的,我感覺有時候數(shù)組作為狀態(tài)發(fā)生改變時宁炫,redux并不能檢測到偿曙,通過打印日志,數(shù)據(jù)確實發(fā)生改變了羔巢,但是確實沒有重新刷新望忆。之前我做vue使用vuex時也遇到過罩阵。我采用的方法不知道是不是規(guī)范的方法,我是在狀態(tài)中又添加了一個布爾的loading,刷新時設(shè)置為ture請求我數(shù)據(jù)設(shè)置為false启摄,通過這個布爾值刷新列表進(jìn)行重新渲染稿壁。
//通過loading 的改變刷新
case types.CAR_SHOW_FETCH :
            return Object.assign({}, state, {
                carShowDataArr: action.carShowDataArr,
                loading:action.loading
            });
  • 這個模塊還遇到個性能問題是有時候狀態(tài)太多,有的狀態(tài)改變并不需要刷新歉备,這時候基礎(chǔ)很重要了傅是,組件的生命周期有這么個方法shouldComponentUpdate(nextProps, nextState) {}當(dāng)這個方法的返回值是YES時會刷新,NO時不會刷新蕾羊,render每次刷新之前都會調(diào)用這個方法喧笔,只有返回值是YES時才會刷新,這個方法中我們可以做很多事情龟再,解決很多性能問題
    車生活
  • 車款詳情
  • 這個界面算是比較復(fù)雜的界面书闸,想想要是讓我用原生寫,我估計要好久可能也寫不好利凑,尤其是下面顏色選擇浆劲,這就體現(xiàn)出H5布局的優(yōu)勢了,簡單哀澈,快梳侨,react-native使用flexBox布局,真心簡單方便日丹,不過這個界面也遇到了一點性能的小問題,每當(dāng)每個色塊點擊時要重新請求數(shù)據(jù)蚯嫌,改變上面的圖片哲虾,也就是車的顏色,當(dāng)我的安卓機(jī)每次點擊切換時择示,TouchableOpacity按鈕自帶的淡入淡出的效果變得非呈眨卡頓了,在onPress執(zhí)行了一個setState的操作栅盲,這個操作需要大量計算工作并且導(dǎo)致了掉幀汪诉。對此的一個解決方案是將onPress處理函數(shù)中的操作封裝到requestAnimationFrame中:
requestAnimationFrame(() => {
            this.setState({
                selectInteriorColor :index,
            });
            const {  interiorColorList,exteriorColorList,actions ,id,detailType} = this.props;
            let inId = interiorColorList[index].id;
            let outId = exteriorColorList[this.state.selectExteriorColor].id;
            actions.getCarInfo({outId,inId,id,detailType});
 });
車款詳情
  • RN 中加載web
  • 這是個webView,這是我純屬顯得蛋疼想用reactNative加載個h5頁面看看啥效果谈秫,請見諒


    WebView

性能優(yōu)化

  • 學(xué)習(xí)了一段時間馬上就要開發(fā)了扒寄,感覺當(dāng)前對于我來說最大的問題還是關(guān)于性能的問題,因為前端基礎(chǔ)比較差拟烫,很多很簡單的東西需要好久才能找到合適的解決方案该编,總結(jié)了幾個常見的性能問題,之后仔細(xì)又閱讀了一遍官方的文檔硕淑,發(fā)現(xiàn)很多問題文檔上都有講课竣,所以文檔還是要臣问辏看啊
  • console.log語句
    • 在運行打好了離線包的應(yīng)用時,控制臺打印語句可能會極大地拖累JavaScript線程
    • 解決方案發(fā)于樟,自己封裝一個打印語句公条,根據(jù)debug是0還是1選擇是否打印,方便我們上線時把打印全都去掉迂曲,推薦一個好用的第三方redux-logger
  • 開發(fā)模式和生產(chǎn)模式是大不相同的靶橱,有時候開發(fā)模式下會很卡,但生產(chǎn)模式就不一樣了奢米。
  • Navigator導(dǎo)航切換抓韩,這個是非常常見的卡頓,可以選擇的解決方法也有很多鬓长,這是我的解決方法,利用官方推薦的這個組件InteractionManager
  • 首先設(shè)置這樣一個狀態(tài)
onstructor(props) {
        super(props);
        this.state={

            renderPlaceholderOnly:true,
        }
    }
  • render方法中進(jìn)行判斷谒拴,renderPlaceholderOnly為ture時給他一個加載頁面顯示false時顯示界面
render() {
        if (this.state.renderPlaceholderOnly) {
              //loading頁
            return this._renderPlaceholderView();
        }
        return (     
               //界面
        )
    }
_renderPlaceholderView() {
        return (
            <View style={{flex:1,backgroundColor:'white',justifyContent:'center',alignItems:'center',}}>
                <Text>Loading...</Text>
            </View>
        );
    }
  • 最后將請求數(shù)據(jù)的方法封裝到下面的方法中InteractionManager.runAfterInteractions是在js動畫結(jié)束時會走里面的回調(diào)。
componentDidMount() {

        InteractionManager.runAfterInteractions(() => {
            this.setState({renderPlaceholderOnly: false});
            this.props.actions.getBrandSource({});
            this.props.actions.getCarTypesource();

        });

    }
  • 關(guān)于listView的性能優(yōu)化
  • initialListSize 這個屬性定義了在首次渲染中繪制的行數(shù)涉波。如果我們關(guān)注于快速的顯示出頁面英上,可以設(shè)置initialListSize為1,然后我們會發(fā)現(xiàn)其他行在接下來的幀中被快速繪制到屏幕上啤覆。而每幀所顯示的行數(shù)由pageSize所決定
  • pageSize在初始渲染也就是initialListSize被使用之后苍日,ListView將利用pageSize來決定每一幀所渲染的行數(shù)。默認(rèn)值為1 —— 但是如果你的頁面很小窗声,而且渲染的開銷不大的話相恃,你會希望這個值更大一些。稍加調(diào)整笨觅,你會發(fā)現(xiàn)它所起到的作用拦耐。
  • scrollRenderAheadDistance在將要進(jìn)入屏幕區(qū)域之前的某個位置,開始繪制一行见剩,距離按像素計算杀糯。如果我們有一個2000個元素的列表,并且立刻全部渲染出來的話苍苞,無論是內(nèi)存還是計算資源都會顯得很匱乏固翰。還很可能導(dǎo)致非常可怕的阻塞羹呵。因此scrollRenderAheadDistance允許我們來指定一個超過視野范圍之外所需要渲染的行數(shù)骂际。
  • removeClippedSubviews當(dāng)這一選項設(shè)置為true的時候,超出屏幕的子視圖(同時overflow
    值為hidden)會從它們原生的父視圖中移除冈欢。這個屬性可以在列表很長的時候提高滾動的性能方援。默認(rèn)為false。這是一個應(yīng)用在長列表上極其重要的優(yōu)化涛癌。Android上犯戏,overflow值總是hidden的送火,所以你不必?fù)?dān)心沒有設(shè)置它。而在iOS上先匪,你需要確保在行容器上設(shè)置了overflow: hidden种吸。
  • 如果你正在使用一個ListView,你必須提供一個rowHasChanged函數(shù)呀非,它通過快速的算出某一行是否需要重繪坚俗,來減少很多不必要的工作。如果你使用了不可變的數(shù)據(jù)結(jié)構(gòu)岸裙,這項工作就只需檢查其引用是否相等猖败。同樣的,你可以實現(xiàn)shouldComponentUpdate函數(shù)來指明在什么樣的確切條件下降允,你希望這個組件得到重繪恩闻。
  • 關(guān)于動畫Animated的使用,盡量使用LayoutAnimation,Animated的接口一般會在JavaScript線程中計算出所需要的每一個關(guān)鍵幀,而LayoutAnimation則利用了Core Animation剧董,使動畫不會被JS線程和主線程的掉幀所影響幢尚。尤其是在動畫過程中有大量的數(shù)據(jù)請求,狀態(tài)改變翅楼。
  • 當(dāng)具有透明背景的文本位于一張圖片上時尉剩,或者在每幀重繪視圖時需要用到透明合成的任何其他情況下,這種現(xiàn)象尤為明顯毅臊。設(shè)置shouldRasterizeIOS或者renderToHardwareTextureAndroid屬性可以顯著改善這一現(xiàn)象理茎。 注意不要過度使用該特性,否則你的內(nèi)存使用量將會飛漲管嬉。在使用時功蜓,要評估你的性能和內(nèi)存使用情況。如果你沒有需要移動這個視圖的需求宠蚂,請關(guān)閉這一屬性。
  • 在iOS上童社,每次調(diào)整Image組件的寬度或者高度求厕,都需要重新裁剪和縮放原始圖片。這個操作開銷會非常大扰楼,尤其是大的圖片呀癣。比起直接修改尺寸,更好的方案是使用transform: [{scale}]的樣式屬性來改變尺寸弦赖。比如當(dāng)你點擊一個圖片项栏,要將它放大到全屏的時候,就可以使用這個屬性蹬竖。
  • Touchable系列組件不能很好的響應(yīng)
  • 有些時候沼沈,如果我們有一項操作與點擊事件所帶來的透明度改變或者高亮效果發(fā)生在同一幀中流酬,那么有可能在onPress函數(shù)結(jié)束之前我們都看不到這些效果。比如在onPress執(zhí)行了一個setState的操作列另,這個操作需要大量計算工作并且導(dǎo)致了掉幀芽腾。對此的一個解決方案是將onPress
    處理函數(shù)中的操作封裝到requestAnimationFrame
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市页衙,隨后出現(xiàn)的幾起案子摊滔,更是在濱河造成了極大的恐慌,老刑警劉巖店乐,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艰躺,死亡現(xiàn)場離奇詭異,居然都是意外死亡眨八,警方通過查閱死者的電腦和手機(jī)腺兴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來踪古,“玉大人含长,你說我怎么就攤上這事》拢” “怎么了拘泞?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長枕扫。 經(jīng)常有香客問我陪腌,道長,這世上最難降的妖魔是什么烟瞧? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任诗鸭,我火速辦了婚禮,結(jié)果婚禮上参滴,老公的妹妹穿的比我還像新娘强岸。我一直安慰自己,他們只是感情好砾赔,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布蝌箍。 她就那樣靜靜地躺著,像睡著了一般暴心。 火紅的嫁衣襯著肌膚如雪妓盲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天专普,我揣著相機(jī)與錄音悯衬,去河邊找鬼。 笑死檀夹,一個胖子當(dāng)著我的面吹牛筋粗,可吹牛的內(nèi)容都是我干的策橘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼亏狰,長吁一口氣:“原來是場噩夢啊……” “哼役纹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起暇唾,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤促脉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后策州,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瘸味,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年够挂,在試婚紗的時候發(fā)現(xiàn)自己被綠了旁仿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡孽糖,死狀恐怖枯冈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情办悟,我是刑警寧澤尘奏,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站病蛉,受9級特大地震影響炫加,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铺然,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一俗孝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧魄健,春花似錦赋铝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至其垄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卤橄,已是汗流浹背绿满。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留窟扑,地道東北人喇颁。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓漏健,卻偏偏與公主長得像,于是被迫代替她去往敵國和親橘霎。 傳聞我的和親對象是個殘疾皇子蔫浆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 開發(fā)環(huán)境配置 參照這里 頁面渲染 組件的渲染需要在自定義 class 中進(jìn)行,每個自定義視圖class中都包含一個...
    cocoawork丶閱讀 339評論 0 0
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,283評論 25 707
  • 本人小白,也是最近才開始學(xué)習(xí)ReactNative,只是想記錄自己的學(xué)習(xí)歷程姐叁,供日后查閱復(fù)習(xí)瓦盛,文中有任何錯誤或者不...
    小唐羽鋒閱讀 1,353評論 0 51
  • 初識React Native 2015年3月26日,FaceBook公司正式對外發(fā)布了React Native 更...
    koala_閱讀 3,103評論 0 7
  • 事情沒到最后呢,不要想得太多外潜,說不定是好事呢原环! 每一件事都有兩面性,塞翁失馬焉知非福处窥,因為一個學(xué)生我竟然跟鵬哥討論...
    曉玖的碎碎念閱讀 187評論 0 0