一、React Native配置環(huán)境
- React Native中文網(wǎng): http://reactnative.cn/docs/0.41/getting-started.html
- React Native環(huán)境配置(簡書):http://www.reibang.com/p/ab07248f6741
二、引入第三方庫 / 組件
第三方庫引入
npm install name(三方庫名) --save 安裝的同時丛忆,將信息寫入package.json中
組件引入(自定義組件)
import TextInputView from '../../components/EF_TextInputView'
三檀头、setState渲染問題
每次調(diào)用this.setState丁眼,都會自動調(diào)用render函數(shù)睛蛛,重新渲染一下界面活合。
(Tip:ListView如果使用這種方法将宪,必須更改一下數(shù)據(jù)源绘闷,但不建議多次使用這種方式渲染界面,可以使用Mbox,學(xué)習(xí)網(wǎng)址:http://v.youku.com/v_show/id_XMjQ4NTA4OTUwOA==.html?spm=a2hzp.8253869.0.0&from=y1.7-2)
constructor(props) {
super(props);
this.state = {
isLoading: true, // 下拉刷新數(shù)據(jù)標(biāo)記
};
}
_this.setState({
isLoading: false,
})
四涧偷、頁面?zhèn)髦祮栴}
1.直接傳值
例如下側(cè)代碼中的 albumId= {this.props.albumId}簸喂,=前面表示參數(shù)名,后面表示要傳的數(shù)據(jù)燎潮。
<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.跳轉(zhuǎn)頁面?zhèn)髦?/h5>
使用Navigator進(jìn)行頁面跳轉(zhuǎn)喻鳄,進(jìn)行傳值時,
Navigator的使用
/*
* 設(shè)置Navigator轉(zhuǎn)場方式
* */
configureScene = (route, routeStack) => {
if (route.type == 'bottom') {
return Navigator.SceneConfigs.FloatFromBottom; // 底部彈出
} else if (route.type == 'fade') {
return Navigator.SceneConfigs.FadeAndroid; // 淡入淡出
}
return Navigator.SceneConfigs.PushFromRight; // 右側(cè)彈出
};
/*
* 傳值
* */
renderScene = (route, navigator) => {
return <route.component navigator={navigator} {...route.passProps} />;//傳值(使用時參數(shù)名passProps要與這里統(tǒng)一)
};
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'
設(shè)置監(jiān)聽
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();
}
發(fā)通知
RCTDeviceEventEmitter.emit('編輯相冊', _this.state.albumId, params);
五确封、封裝數(shù)據(jù)請求
/*
* post請求發(fā)送說說
* params:參數(shù)
* callback:回調(diào)函數(shù)
* */
static postShortposts(params, callback) {
url = API + 'shortposts/';
let paramsStr = '';
console.log('參數(shù):' + JSON.stringify(params));
if (params) {
let paramsArray = [];
//拼接參數(shù)
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': 'application/x-www-form-urlencoded'
},
body: paramsStr,
})
.then((response) => response.json())
.then((responseJSON) => {
callback(responseJSON)
}).done();
}
六除呵、flex布局
對于學(xué)習(xí)過CSS的人,直接按照以前的方式理解就行
http://reactnative.cn/docs/0.41/layout-with-flexbox.html#content
七爪喘、this指向問題
this在RN中就是指這個類本身,但是經(jīng)常會報(bào)一些錯誤:not an object(this.)或者not a funcation等,這類問題一般有兩種解決辦法
1.在render中里面調(diào)用方法的時候,使用this.方法名.bind(this),重新綁定一下this
2.在方法里面, let _this = this,使用_this來調(diào)用本身類
八颜曾、性能優(yōu)化問題
1、聲明方法函數(shù)時秉剑,要盡量使用 方法名= ()=> {}泛豪,這樣會減少方法引用的次數(shù)。然后在調(diào)用的時候侦鹏,直接使用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外面聲明即可跨释,調(diào)用的時候 this.屬性名胸私,這樣就不會調(diào)用render函數(shù)了,不會重新渲染界面鳖谈。
4岁疼、在render中使用const {屬性}= this.prps,直接使用屬性名就可以調(diào)用蚯姆。這樣可以不用再state里面使用了五续,減少了渲染的次數(shù)。
5龄恋、推遲render的過程疙驾,在數(shù)據(jù)請求完之后,使用InteractionManager.runAfterInteractions( ()=> {this.setStates({})})
6郭毕、使用mbox它碎,只改變需要改變的,不重新全部渲染显押。