首先是搭建环境
使用入门
我们要修改 App.js
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Hello, world!</Text>
</View>
);
let pic = {
uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
};
return (
<Image source={pic} style={{width: 193, height: 110}} />
);
我们先这么理解:一个括号表示变量,两个括号表示属性
props
是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变。 对于需要改变的数据,我们需要使用state
。
一般来说,你需要在 constructor 中初始化state
,然后在需要修改时调用setState
方法。
class Blink extends Component {
constructor(props) {
super(props);
this.state = { isShowingText: true }; // 指定 state
// 每1000毫秒对showText状态做一次取反操作
setInterval(() => {
this.setState(previousState => {
return { isShowingText: !previousState.isShowingText };
});
}, 1000);
}
render() {
// 根据当前showText的值决定是否显示text内容
if (!this.state.isShowingText) {
return null;
}
return (
<Text>{this.props.text}</Text>
);
}
}
export default class BlinkApp extends Component {
render() {
return (
<View>
<Blink text='I love to blink' />
<Blink text='Yes blinking is so great' />
<Blink text='Why did they ever take this out of HTML' />
<Blink text='Look at me look at me look at me' />
</View>
);
}
}
create 样式,其中在数组中位置居后的样式对象比居前的优先级更高,这样可以间接实现样式的继承。
export default class LotsOfStyles extends Component {
render() {
return (
<View>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigBlue}>just bigBlue</Text>
<Text style={[styles.bigBlue, styles.red]}>bigBlue, then red</Text>
<Text style={[styles.red, styles.bigBlue]}>red, then bigBlue</Text>
</View>
);
}
}
const styles = StyleSheet.create({
bigBlue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
宽高与弹性宽高
export default class FixedDimensionsBasics extends Component {
render() {
return (
<View>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
<View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
</View>
// 试试去掉父View中的`flex: 1`。
// 则父View不再具有尺寸,因此子组件也无法再撑开。
// 然后再用`height: 300`来代替父View的`flex: 1`试试看?
<View style={{flex: 1}}>
<View style={{flex: 1, backgroundColor: 'powderblue'}} />
<View style={{flex: 2, backgroundColor: 'skyblue'}} />
<View style={{flex: 3, backgroundColor: 'steelblue'}} />
</View>
);
}
}
文本输入
export default class PizzaTranslator extends Component {
constructor(props) {
super(props);
this.state = {text: ''};
}
_onPressButton() {
Alert.alert('You tapped the button!')
}
render() {
return (
<View style={{padding: 10}}>
<TextInput
style={{height: 40}}
placeholder="Type here to translate!"
onChangeText={(text) => this.setState({text})}
/>
<Text style={{padding: 10, fontSize: 42}}>
{this.state.text.split(' ').map((word) => word && '🍕').join(' ')}
</Text>
<Button // button 点击事件
onPress={this._onPressButton}
title="Press Me"
/>
</View>
);
}
}
Touchable 系列组件
-
TouchableHighlight
制作按钮或者链接 -
TouchableNativeFeedback
在 Android 上, 用户手指按下时形成类似墨水涟漪的视觉效果 -
TouchableOpacity
会在用户手指按下时降低按钮的透明度 -
Touchablewithoutfeedback
在处理点击事件的同时不显示任何视觉反馈
滚动视图:ScrollView
是一个通用的可滚动的容器,你可以在其中放入多个组件和视图,而且这些组件并不需要是同类型的。ScrollView 不仅可以垂直滚动,还能水平滚动(通过horizontal
属性来设置)
长列表:FlatList
或是 SectionList
-
FlatList
组件用于显示一个垂直的滚动列表,其中的元素之间结构近似而仅数据不同。更适于长列表数据,且元素个数可以增删。组件必须的两个属性是data
和renderItem
。data是列表的数据源,而renderItem则从数据源中逐个解析数据,然后返回一个设定好格式的组件来渲染。
export default class FlatListBasics extends Component {
render() {
return (
<View style={styles.container}>
<FlatList
data={[
{key: 'Devin'},
{key: 'Jackson'},
{key: 'James'},
{key: 'Joel'},
{key: 'John'},
{key: 'Jillian'},
{key: 'Jimmy'},
{key: 'Julie'},
]}
renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
/>
</View>
);
}
}
-
SectionList
渲染的是一组需要分组的数据,也许还带有分组标签的
export default class SectionListBasics extends Component {
render() {
return (
<View style={styles.container}>
<SectionList
sections={[
{title: 'D', data: ['Devin']},
{title: 'J', data: ['Jackson', 'James', 'Jillian', 'Jimmy', 'Joel', 'John', 'Julie']},
]}
renderItem={({item}) => <Text style={styles.item}>{item}</Text>}
renderSectionHeader={({section}) => <Text style={styles.sectionHeader}>{section.title}</Text>}
keyExtractor={(item, index) => index}
/>
</View>
);
}
}
网络
Fetch 方法会返回一个Promise
,具体可查阅Request文档
fetch('https://facebook.github.io/react-native/movies.json', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.movies,
}, function(){
});
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
});
注意不能使用 jQuery,因为 jQuery 中还使用了很多浏览器中才有而 RN 中没有的东西
示例
var REQUEST_URL =
"https://raw.githubusercontent.com/facebook/react-native/0.51-stable/docs/MoviesExample.json";
export default class SampleAppMovies extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
loaded: false
};
// 在ES6中,如果在自定义的函数里使用了this关键字,则需要对其进行“绑定”操作,否则this的指向会变为空
// 像下面这行代码一样,在constructor中使用bind是其中一种做法(还有一些其他做法,如使用箭头函数等)
this.fetchData = this.fetchData.bind(this);
}
componentDidMount() {
this.fetchData();
}
fetchData() {
fetch(REQUEST_URL)
.then(response => response.json())
.then(responseData => {
// 注意,这里使用了this关键字,为了保证this在调用时仍然指向当前组件,我们需要对其进行“绑定”操作
this.setState({
data: this.state.data.concat(responseData.movies),
loaded: true
});
});
}
render() {
if (!this.state.loaded) {
return this.renderLoadingView();
}
return (
<FlatList
data={this.state.data}
renderItem={this.renderMovie}
style={styles.list}
keyExtractor={item => item.id}
/>
);
}
renderLoadingView() {
return (
<View style={styles.container}>
<Text>Loading movies...</Text>
</View>
);
}
renderMovie({ item }) {
// { item }是一种“解构”写法,请阅读ES2015语法的相关文档
// item也是FlatList中固定的参数名,请阅读FlatList的相关文档
return (
<View style={styles.container}>
<Image
source={{ uri: item.posters.thumbnail }}
style={styles.thumbnail}
/>
<View style={styles.rightContainer}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.year}>{item.year}</Text>
</View>
</View>
);
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF"
},
rightContainer: {
flex: 1
},
title: {
fontSize: 20,
marginBottom: 8,
textAlign: "center"
},
year: {
textAlign: "center"
},
thumbnail: {
width: 53,
height: 81
},
list: {
paddingTop: 20,
backgroundColor: "#F5FCFF"
}
});