Lec 11
Lec 11
2
RN - architecture
3
RN – key points
• React Native is a JavaScript framework/library for writing real,
natively rendering iOS, Android and UWP applications.
• Mostly just V part of the application architecture (MVC) paradigm.
• FlexBox layout
• Reuse almost all non-UI code, most UI code among different
platforms
• ES6
• React isn’t framework, it’s a (view)library – state management,
routing, … - up to developer!
4
RN – components - lets get started!
5
RN – js dev environment
• Visual Studio Code (or Atom,….)
• Node and NPM
• npm install -g react-native-cli
• Xcode (if you’re working on a Mac)
• Android Studio
RN - eslint
],
1,
4
"no-console": 0,
"no-unused-vars": [
1,
• .eslintrc.json {
"vars": "local",
"args": "none"
}
],
"react/forbid-prop-types": 1,
"react/jsx-boolean-value": 1,
"react/jsx-closing-bracket-location": [
1,
{
"selfClosing": "after-props",
"nonEmpty": "after-props"
}
],
"react/jsx-curly-spacing": [
1,
"never",
{
"spacing": {
"objectLiterals": "always"
}
}
],
"react/jsx-indent-props": 1,
"react/jsx-key": 1,
"react/jsx-max-props-per-line": 1,
9
"react/jsx-no-duplicate-props": 1,
RN – VSCode custom settings
• VSCode > Code > Preferences > User Settings
10
RN – initial view – login screen
• flexbox is used for element positions and scaling
– https://css-tricks.com/snippets/css/a-guide-to-flexbox/
• Typical elements
– View
– Text
– Image
– TextInput
– TouchableHighlight
11
RN – initial view – login screen
• Create new react component
• Keep app code in new directory - app
• Add new file – Login.js
12
import React, { Component } from 'react';
import {
• Import },
alignItems: 'center',
});
• Styles - flexbox class Login extends Component {
– constructor(props) this.state = {
};
– this.state for initial state management }
}
13
module.exports = Login;
RN – initial view – index.*.js
import React, { Component } from 'react';
import {
• Import created module AppRegistry,
StyleSheet,
View,
} from 'react-native';
});
• iOS
– cmd+r for reload
– cmd+d for dev menu
– Enable reload
• Android
– cmd+m for dev menu
– Enable reload
15
RN – design view
16
RN – design view
info
<TextInput
onChangeText={(text) => this.setState({ username: text }) }
placeholder="username"
style={styles.input} />
• {} – for js code <TextInput
onChangeText={(text) => this.setState({ password: text }) }
placeholder="password"
• {{}} - for js objects secureTextEntry
style={styles.input} />
<TouchableHighlight
style={styles.button}>
<Text
style={styles.buttonText}>
Log in
</Text>
</TouchableHighlight> 17
</View>
const styles = StyleSheet.create({
container: {
backgroundColor: '#F5FCFF',
RN – design view
flex: 1,
paddingTop: 60,
alignItems: 'center',
padding: 10,
},
logo: {
width: 194,
• Styles },
height: 65,
heading: {
fontSize: 30,
marginTop: 20,
},
input: {
alignSelf: 'stretch',
height: 50,
marginTop: 10,
padding: 4,
fontSize: 18,
borderWidth: 1,
borderColor: '#48bbec',
},
button: {
height: 50,
backgroundColor: '#48BBEC',
alignSelf: 'stretch',
marginTop: 10,
justifyContent: 'center',
},
buttonText: {
fontSize: 22,
color: '#FFF',
alignSelf: 'center',
},
});
18
RN – es6 and “this”
• ”this” is scoped differently in various JS code parts
• In arrow functions – surrounding class
• Class functions – function itsself
• Bind class scope “this” to function scope in class constructor
– this.someFunction = this.someFunction.bind(this);
19
RN - onPress
class Login extends Component {
constructor(props) {
super(props);
this.onLoginPressed = this.onLoginPressed.bind(this);
this.state = {
};
}
onLoginPressed() {
console.log(`Log in - user:${this.state.username} pass:${this.state.password}`);
console.log(this);
}
render() {
return (
<View style={styles.container}>
<TouchableHighlight
onPress={this.onLoginPressed.bind(this) }
style={styles.button}>
<Text
style={styles.buttonText}>
Log in
</Text>
</TouchableHighlight>
</View>
);
}
} 20
RN – debugging in Chrome
Dev menu
Debug JS Remotely
Open dev console in
Chrome
Monitor console
Source code in
debuggerWorker.js tree
Breakpoints!!!!!
21
RN – state, ActivityIndicator
• Add variable to state – to display ActivityIndicator after button
touch
• Update state in press handler
• RN monitors state (it is special object) and redraws screen on
updates
• Add ActivityIndicator to view
22
RN – state, ActivityIndicator
import React, { Component } from 'react'; class Login extends Component {
import {
ActivityIndicator, constructor(props) {
Image, super(props);
StyleSheet, this.onLoginPressed = this.onLoginPressed.bind(this);
Text, this.state = {
TextInput, showProgress: false,
TouchableHighlight, };
View, }
} from 'react-native';
onLoginPressed() {
console.log(`Log in - user:${this.state.username} pass:${this.state.password}`);
this.setState({ showProgress: true });
}
render() {
return (
<View style={styles.container}>
...
<ActivityIndicator
animating={this.state.showProgress}
hidesWhenStopped
size="large"
style={styles.loader}/>
</View>
);
}
} 23
RN – Rest request (Web API)
• Demo app available on my github
• RN is running on very limited JS engine
• Use Fetch for http requests – promise based
– Note: Errors thrown by rejected Promises need to be caught, or they
will be swallowed silently
fetch('https://mywebsite.com/endpoint.php')
.then((response) => response.text())
.then((responseText) => {
console.log(responseText);
})
.catch((error) => {
console.warn(error);
});
24
RN - AuthService
• OAuth2 Web API token
– Post
• https://servername/Token
– Request headers
• Content-Type: application/x-www-form-urlencoded
– Request body (urlencoded)
• grant_type=password&[email protected]&password=parool
25
RN - AuthService
• Encode formbody
const loginDetails = {
grant_type: 'password',
username: credentials.username,
• Callback –
password: credentials.password,
};
formBody = formBody.join('&');
.then((response) => {
}
return response;
// new it up immediately
module.exports = new AuthService(); 27
RN – using AuthService
render() {
let errorCtrl = <View />;
if (!this.state.success && this.state.badCredentials) {
• Tabbed layout
• Multiple screens within one Tab
• Provide callbacks for login and logout
29
RN - navigation
• Main view
– IOS
• TabBarIOS and NavigatorIOS File extension
– Android BigButton.ios.js
BigButton.android.js
• DrawerLayoutAndroid
import BigButton from './components/BigButton';
• Platform detection Platform module
var { Platform } = ReactNative;
Platform.OS === 'ios' ( or 'android')
var Component = Platform.select({
ios: () => require('ComponentIOS'),
android: () => require('ComponentAndroid'),
})(); 30
RN - Navigation
• Move all logic out of index.*.js
– App.js – analog to Login.js
• App.js
– Add state – isLoggedIn
– Add callback to Login for successful login
• <Login onLogin={this.onLogin.bind(this) } />
– Add onLogin method to App
• onLogin() { this.setState({ isLoggedIn: true }); }
– In render, check for state and select correct component
– Add callback to AppContainer for logout
31
Next week in lab
• Install Android Studio
• Install react-native
• Get my demo app off of github and get it working on your
emulator
• Replace the API I used with the API of your choice to make a
new app
32