React Native Introduction
React Native is not really a hybrid app framework
write once, run anywherelearn once, write anywhere
Let's compare it to hybrid apps
React Native | Hybrid |
---|---|
Shared and platform exclusive code | All code shared |
Javascript + JSX | Javascript + HTML + CSS |
Live and hot reload | Live and hot reload |
No WebView | WebView |
Native performance | Browser performance |
Relatively new | Lot's of mature plugins |
No WebView? Is Javascript compiled to binary then?
- Javascript is run in a separate thread, using Javascript engine, named JavaScriptCore, which also powers Safari
- While debugging with Chrome, the code is actually run within Chrome's V8 engine and communicates with app through web sockets
Not at all!
Here's the whole picture
Three parts of React Native
- React Native - Native Side
- React Native - Javascript Side
- React Native - Bridge
Basic UI components
View | The most fundamental component for building a UI. |
Text | A component for displaying text. |
Image | A component for displaying images. |
TextInput | A component for inputting text into the app via a keyboard. |
ScrollView | Provides a scrolling container that can host multiple components and views. |
Button | A basic button component for handling touches that should render nicely on any platform. |
Picker | Renders the native picker component on iOS and Android. |
Slider | A component used to select a single value from a range of values. |
Switch | Renders a boolean input. |
FlatList | A component for rendering performant scrollable lists. |
SectionList | Like FlatList, but for sectioned lists. |
Platform specific components
- DatePickerIOS
- AlertIOS
- TabBarIOS
- ImagePickerIOS
- PushNotificationIOS
- BackHandler
- DatePickerAndroid
- TimePickerAndroid
- PermissionsAndroid
- ToastAndroid
- ViewPagerAndroid
- ToolbarAndroid
Other shared components and classes
- StatusBar
- Modal
- StyleSheet
- KeyboardAvoidingView
- WebView
Let's take a look at the code
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { AppRegistry, Text, TouchableOpacity } from 'react-native'
import { Metrics, Colors, Fonts } from '../Themes'
const styles = {
text: {
...Fonts.style.h5,
color: Colors.snow,
marginVertical: Metrics.baseMargin
}
}
export class Button extends Component {
static propTypes = {
text: PropTypes.string,
onPress: PropTypes.func
}
render () {
return (
<TouchableOpacity onPress={this.props.onPress}>
<Text style={styles.text}>{this.props.text}</Text>
</TouchableOpacity>
)
}
}
AppRegistry.registerComponent('ButtonApp', () => Button)
React Native navigation
Currently suggested solution is to use react-community/react-navigation
First screen
import React from 'react';
import {
AppRegistry,
Text,
} from 'react-native';
import { StackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
return <Text>Hello, Navigation!</Text>;
}
}
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
});
AppRegistry.registerComponent('SimpleApp', () => SimpleApp);
Here's the effect
Android
iOS
Second View
class ChatScreen extends React.Component {
static navigationOptions = {
title: 'Chat with Lucy',
};
render() {
return (
<View>
<Text>Chat with Lucy</Text>
</View>
);
}
}
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>Hello, Chat App!</Text>
<Button
onPress={() => navigate('Chat')}
title="Chat with Lucy"
/>
</View>
);
}
}
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
Chat: { screen: ChatScreen },
});
Here's the effect
Android
iOS
Testing
- Jest
- Enzyme (doesn't support mounting)
- Tree snapshots
Tree snapshots
import renderer from 'react-test-renderer';
test('Link renders correctly', () => {
const tree = renderer.create(
<Link page="http://www.facebook.com">
Facebook
</Link>
).toJSON();
expect(tree).toMatchSnapshot();
});
exports[`Link renders correctly 1`] = `
<a
className="normal"
href="http://www.facebook.com"
onMouseEnter={[Function bound _onMouseEnter]}
onMouseLeave={[Function bound _onMouseLeave]}>
Facebook
</a>
`;
There's a really nice boilerplate
Ignite CLI
Ignite CLI
$ npm install -g ignite-cli
$ ignite new PizzaApp
$ cd PizzaApp
$ ignite add maps
$ ignite add vector-icons
$ ignite generate screen PizzaLocationList
$ ignite generate component PizzaLocation
$ ignite generate map StoreLocator
$ ignite add i18n
Run the app
$ react-native run-ios
$ react-native run-android
React Native Introduction
By Patryk Ziemkowski
React Native Introduction
- 699