-
- Notifications
You must be signed in to change notification settings - Fork 65
Description
安装
我们推荐使用Homebrew来安装Node和Watchman。在命令行中执行下列命令安装:
brew install node brew install watchman如果你已经安装了 Node,请检查其版本是否在 v8.3 以上。安装完 Node 后建议设置 npm 镜像以加速后面的过程(或使用科学上网工具)。
注意:不要使用 cnpm!cnpm 安装的模块路径比较奇怪,packager 不能正常识别!
npm config set registry https://registry.npm.taobao.org --global npm config set disturl https://npm.taobao.org/dist --globalYarn、React Native 的命令行工具(react-native-cli)
Yarn是 Facebook 提供的替代 npm 的工具,可以加速 node 模块的下载。React Native 的命令行工具用于执行创建、初始化、更新项目、运行打包服务(packager)等任务
npm install -g yarn react-native-cli安装完 yarn 后同理也要设置镜像源:
yarn config set registry https://registry.npm.taobao.org --global yarn config set disturl https://npm.taobao.org/dist --global创建项目
使用 React Native 命令行工具来创建一个名为AwesomeProject的新项目:
react-native init AwesomeProject cd AwesomeProject && npm install启动
进入ios文件夹用Xcode打开AwesomeProject.xcodeproj文件,并启动

props
大多数组件在创建时就可以使用各种参数来进行定制。用于定制的这些参数就称为props属性。
class Greeting extends Component { render() { return ( <View style={{alignItems: 'center', marginTop: 50}}> <Text>Hello {this.props.name}!</Text> </View> ); } } type Props = {}; export default class App extends Component<Props> { render() { return ( <View style={styles.container}> <Text style={styles.welcome}>Welcome1 to React Native!</Text> <Text style={styles.instructions}>To get started, edit App.js</Text> <Text style={styles.instructions}>{instructions}</Text> <Greeting name='Rexxar' /> <Greeting name='Jaina' /> <Greeting name='Valeera' /> </View> ); } }布局
在组件样式中使用flex可以使其在可利用的空间中动态地扩张或收缩。一般而言我们会使用flex:1来指定某个组件扩张以撑满所有剩余的空间。如果有多个并列的子组件使用了flex:1,则这些子组件会平分父容器中剩余的空间。如果这些并列的子组件的flex值不一样,则谁的值更大,谁占据剩余空间的比例就更大(即占据剩余空间的比等于并列组件间flex值的比)。
<View style={{ flex: 1 }}> <View style={{ flex: 1, backgroundColor: 'powderblue' }} /> <View style={{ flex: 2, backgroundColor: 'skyblue' }} /> <View style={{ flex: 3, backgroundColor: 'steelblue' }} /> </View>组件
可以新建src/components 文件夹新建Greeting.js,并在App.js中引入import Greeting from './components/Greeting/Greeting.js';,并使用<Greeting name='Eno Yao’ />
import React, { Component } from 'react'; import { Text, View } from 'react-native'; export default class Greeting extends Component { render() { return ( <View style={{ alignItems: 'center', marginTop: 50 }}> <Text>Hello {this.props.name}!</Text> </View> ); } }事件
点击这个按钮会调用onPress函数,具体作用就是显示一个 alert 弹出框。
| react | react-native |
|---|---|
| onClick | onPress |
| onChange | onChangeText |
import React, { Component } from 'react'; import { Text, View, Button, Alert } from 'react-native'; export default class Greeting extends Component { render() { return ( <View style={{ alignItems: 'center', marginTop: 50 }}> <Text>Hello {this.props.name}!</Text> <Button onPress={() => { Alert.alert("你点击了按钮!"); }} title="点我!" /> </View> ); } }处理文本输入
TextInput是一个允许用户输入文本的基础组件。它有一个名为onChangeText的属性,此属性接受一个函数,而此函数会在文本变化时被调用。另外还有一个名为onSubmitEditing的属性,会在文本被提交后(用户按下软键盘上的提交键)调用。
<TextInput style={{ height: 40 }} placeholder="Type here to translate!" onChangeText={(text) => this.setState({ text })} /> <TextInput // style={{ height: 40 }} placeholder="Type here to translate!" onChangeText={this.onChangeText.bind(this)} /> // js onChangeText(text) { console.log(text) this.setState({ text }) }导航
在你的React Native项目中安装react-navigation这个包
yarn add react-navigation # or with npm # npm install --save react-navigation然后,安装react-native-gesture-handler
yarn add react-native-gesture-handler # or with npm # npm install --save react-native-gesture-handlerLink所有的原生依赖,这一步是必须的,之前漏了这一步在这里花费了很多时间
react-native link react-native-gesture-handler # or react-native link在App.js中把代码替换为下面这些
import React, { Component } from 'react'; import { Text, View, Button } from 'react-native'; import { createAppContainer, createStackNavigator, StackActions, NavigationActions } from 'react-navigation'; // Version can be specified in package.json class HomeScreen extends Component { render() { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Home Screen</Text> <Button title="Go to Details" onPress={() => { this.props.navigation.dispatch(StackActions.reset({ index: 0, actions: [ NavigationActions.navigate({ routeName: 'Details' }) ], })) }} /> </View> ); } } class DetailsScreen extends Component { render() { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Details Screen</Text> </View> ); } } const AppNavigator = createStackNavigator({ Home: { screen: HomeScreen, }, Details: { screen: DetailsScreen, }, }, { initialRouteName: 'Home', }); export default createAppContainer(AppNavigator);导航跳转
<Button title="Go to Home" onPress={() => this.props.navigation.navigate('Home')} />将路由页面封装模块化封装进组件里面
import { createAppContainer, createStackNavigator } from 'react-navigation'; // Version can be specified in package.json import DetailsScreen from './src/components/DetailsScreen/DetailsScreen' import HomeScreen from './src/components/HomeScreen/HomeScreen' const AppNavigator = createStackNavigator({ Home: { screen: HomeScreen, }, Details: { screen: DetailsScreen, }, }, { initialRouteName: 'Home', }); export default createAppContainer(AppNavigator);导航栏标题
class HomeScreen extends React.Component { static navigationOptions = { title: 'Home', }; }导航栏按钮
class LogoTitle extends React.Component { render() { return ( <Image source={require('../../assets/spiro.png')} style={{ width: 30, height: 30 }} /> ); } } export default class DetailsScreen extends Component { static navigationOptions = { title: 'Detail', headerTitle: <LogoTitle />, headerRight: ( <Button title="菜单" onPress={() => alert('This is a button!')} title="Info" color="#58bc58" /> ), }; // other code }底部导航条
import { createAppContainer, createStackNavigator, createBottomTabNavigator } from 'react-navigation'; // Version can be specified in package.json import DetailsScreen from './src/components/DetailsScreen/DetailsScreen' import HomeScreen from './src/components/HomeScreen/HomeScreen' import MineScreen from './src/components/MineScreen/MineScreen' const MineNavigator = createStackNavigator({ Mine: { screen: MineScreen, }, Details: { screen: DetailsScreen, }, }, { initialRouteName: 'Mine', }); const HomeNavigator = createStackNavigator({ Home: { screen: HomeScreen, }, Details: { screen: DetailsScreen, }, }, { initialRouteName: 'Home', }); const TabNavigator = createBottomTabNavigator({ Home: HomeNavigator, Mine: MineNavigator, }, { tabBarOptions: { activeTintColor: 'tomato', inactiveTintColor: 'gray', }, }); export default createAppContainer(TabNavigator);网络
React Native 提供了和 web 标准一致的Fetch API,用于满足开发者访问网络的需求。如果你之前使用过XMLHttpRequest(即俗称的 ajax)或是其他的网络 API,那么 Fetch 用起来将会相当容易上手。
async componentDidMount() { try { let response = await fetch('https://cnodejs.org/api/v1/topics'); console.log(response.json()); } catch (error) { console.error(error); } } // or async componentDidMount() { var request = new XMLHttpRequest(); request.onreadystatechange = (e) => { if (request.readyState !== 4) { return; } if (request.status === 200) { console.log('success', request.responseText); } else { console.warn('error'); } }; request.open('GET', 'https://cnodejs.org/api/v1/topics'); request.send(); }基础组件
Picker
本组件可以在iOS和Android上渲染原生的选择器Picker
import React, { Component } from 'react'; import { Text, View, Picker } from 'react-native'; export default class HomeScreen extends Component { constructor(props) { super(props); this.state = { language: 'java', itemIndex: 0, pickers: [{ label: 'Java', value: 'java' }, { label: 'JavaScript', value: 'js' }, { label: 'Python', value: 'py' }] }; this.setDate = this.setDate.bind(this); } render() { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Picker selectedValue={this.state.language} style={{ height: 50, width: 100 }} onValueChange={(itemValue, itemIndex) => this.setState({ language: itemValue, itemIndex })}> { this.state.pickers.map((item, index) => { return (<Picker.Item key={index} label={item.label} value={item.value} />) }) } </Picker> <Text>{this.state.language}{this.state.itemIndex}</Text> </View> ); } setDate(newDate) { this.setState({ chosenDate: newDate }) } }ScrollView && FlatList
能实现下拉刷新
import React, { Component } from 'react'; import { Text, ScrollView, FlatList, StyleSheet, RefreshControl } from 'react-native'; export default class HomeScreen extends Component { constructor(props) { super(props); this.state = { refreshing: false, }; } _onRefresh = () => { this.setState({ refreshing: true }); setTimeout(() => { this.setState({ refreshing: false }); }, 2000) } render() { return ( <ScrollView refreshControl={ <RefreshControl title='下拉刷新' titleColor='#58bc58' refreshing={this.state.refreshing} onRefresh={this._onRefresh} />} contentContainerStyle={styles.contentContainer}> <Text style={styles.TextStyle}>1</Text> </ScrollView> ); } } const styles = StyleSheet.create({ contentContainer: { paddingVertical: 20, padding: 20 }, TextStyle: { color: 'red', borderStyle: 'solid' } });FlatList更适于长列表数据,且元素个数可以增删。和ScrollView不同的是,FlatList并不立即渲染所有元素,而是优先渲染屏幕上可见的元素。
FlatList组件必须的两个属性是data和renderItem。data是列表的数据源,而renderItem则从数据源中逐个解析数据,然后返回一个设定好格式的组件来渲染。
import React, { Component } from 'react'; import { Text, ScrollView, FlatList, StyleSheet, RefreshControl } from 'react-native'; export default class HomeScreen extends Component { constructor(props) { super(props); this.state = { refreshing: false, data: [] }; } async _onRefresh() { this.setState({ refreshing: true }); var self = this; var request = new XMLHttpRequest(); request.onreadystatechange = (e) => { if (request.readyState !== 4) { return; } if (request.status === 200) { console.log('success', JSON.parse(request.responseText).data); self.setState({ data: this.state.data.concat(JSON.parse(request.responseText).data) }) self.setState({ refreshing: false }); } else { console.warn('error'); } }; request.open('GET', 'https://cnodejs.org/api/v1/topics'); request.send(); } async componentDidMount() { this._onRefresh(); } render() { return ( <FlatList refreshControl={ <RefreshControl title='下拉刷新' titleColor='#58bc58' refreshing={this.state.refreshing} onRefresh={this._onRefresh.bind(this)} />} contentContainerStyle={styles.contentContainer} data={this.state.data} renderItem={({ item }) => <Text style={styles.item}>{item.title}</Text>} keyExtractor={(item) => item.id} /> ); } } const styles = StyleSheet.create({ contentContainer: { paddingVertical: 20, padding: 20 }, TextStyle: { color: 'red', borderStyle: 'solid' } });实现上拉刷新
<FlatList onEndReached={this.onEndReached.bind(this)} onEndReachedThreshold="0.05" />






