SlideShare una empresa de Scribd logo
1 de 71
Descargar para leer sin conexión
How to React Native
Дмитрий Ульянов
JavaScript Developer
linkedin.com/in/drukas16
2 проекта
10 месяцев
2-3 JS разработчика
1 нативный разработчик
Кто использует React Native?
React
Чем хорош React?
Декларативность
Компонентный подход
One way data flow
Virtual DOM
React - это reconciler
ReactDOM - это renderer
React Native - тоже renderer
JS Native
Bridge
JS
Движок JavaScript Core.
Babel под капотом и свой
react-native пресет
Поддержка ES6 и ES7 фич
Полифиллы для ES6-ES7 методов
Object, Array и String;
а также для XMLHttpRequest, fetch,
консоли, тайм-аутов и тд.
Быстрый старт
Create React Native App
expo.io
Компоненты и стили
components/text/styles.js
import { StyleSheet } from 'react-native'
import * as Styles from '@styles'
export default StyleSheet.create({
default: {
fontSize: Styles.fontSizes.normal,
fontFamily: Styles.fonts.primaryFont,
color: Styles.colors.dark,
},
bold: {
fontWeight: ‘bold’
},
"/* other styles "*/
})
import { create } from ‘react-native-platform-stylesheet'
export default create({
default: {
fontSize: 18,
ios: {
fontFamily: 'Helvetica'
},
android: {
fontFamily: 'Roboto'
}
}
})
components/text/styles.js, платформозависимый код
import { create } from ‘react-native-platform-stylesheet'
export default create({
default: {
fontSize: 18,
ios: {
fontFamily: 'Helvetica'
},
android: {
fontFamily: 'Roboto'
}
}
})
components/text/styles.js, платформозависимый код
{
"/* ""... "*/
"rnpm": {
"assets": [
"fonts"
]
}
}
Кладем свои шрифты в fonts/
и обновляем package.json
$ react-native link assets
🎉🎉🎉🎉🎉
import styles from './styles.js'
const Text = ({children, ""...props}) !=> {
const {
bold, color, style: styleExtension,
""...otherProps
} = props
const style = [
styles.default, styleExtension,
bold !&& styles.bold, color !&& { color },
]
return (
<RNText {""...otherProps} style={style}>
{children}
"</RNText>
)
}
components/text/index.js, теперь со стилями
import styles from './styles.js'
const Text = ({children, ""...props}) !=> {
const {
bold, color, style: styleExtension,
""...otherProps
} = props
const style = [
styles.default, styleExtension,
bold !&& styles.bold, color !&& { color },
]
return (
<RNText {""...otherProps} style={style}>
{children}
"</RNText>
)
}
components/text/index.js, теперь со стилями
Использование компонента Text
<View>
<Text>Default text!"</Text>
<Text bold>Bold text!"</Text>
<Text color=“teal”>
Colored text!
"</Text>
"</View>
Использование компонента Text
<View>
<Text>Default text!"</Text>
<Text bold>Bold text!"</Text>
<Text color=“teal”>
Colored text!
"</Text>
"</View>
import Color from 'color'
const teal = Color('teal')
const gray = Color('dimgray')
const darker = color !=> color.darken(0.25)
const withOpacity = color !=> color.alpha(0.8)
export default {
dark: gray,
darker: darker(gray),
primary: teal,
primaryWithOpacity: withOpacity(teal),
}
styles/colors.js, используем npm модуль color
Платформозависимый код
const OS = Platform.OS "// 'android' or 'ios'
const platform = Platform.select({
ios: 'ios',
android: 'android'
})
├── filename.js "// кросплатформенный файл
├── filename.ios.js "// iOS
└── filename.android.js "// Android
Готовые компоненты
NativeBase
• MRN

• React Native Material Design

• React Native Material Kit
Анимации
Animated API LayoutAnimation API
class SpinningImage extends React.Component {
spinValue = new Animated.Value(0)
componentDidMount() { this.spin() }
spin = () => {
this.spinValue.setValue(0)
Animated.timing(this.spinValue, {
toValue: 1,
duration: 2000,
easing: Easing.linear,
useNativeDriver: true,
}).start(this.spin)
}
render() {
const spin = this.spinValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg']
})
const transform = [{rotate: spin}]
const style = [styles.image, {transform}]
return (
<View>
<Animated.Image style={style}
source={myImage}/>
</View>
)
}
}
if (Platform.OS === 'android') {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
class BoxWithSizeChanges extends React.Component {
state = {size: 200}
increaseSize = () => {
LayoutAnimation.spring()
// OR LayoutAnimation.configureNext(CUSTOM_CONFIG)
this.setState(state => ({size: state.size + 50}))
}
render() {
const {size} = this.state
const sizes = {height: size, width: size}
const style = [styles.box, sizes]
return (
<View>
<Box style={style}/>
<Button onPress={this.increaseSize}
title=‘Make him bigger!’/>
</View>
)
}
}
Animated API LayoutAnimation API
Real World React Native
Animations
oblador/react-native-animatable
<Animatable.Text animation="slideInDown"
iterationCount={5}
direction="alternate">
Up and down you go
</Animatable.Text>
<Animatable.Text animation="pulse"
easing="ease-out"
iterationCount="infinite"
style={{textAlign: 'center'}}>
❤
</Animatable.Text>
Навигация
React Native решения “из коробки”
NavigatorIOS
Navigator
NavigationExperimental
React Native решения “из коробки”
NavigatorIOS
Navigator
NavigationExperimental
Комьюнити решения
native-navigation
ex-navigation
react-native-navigation
react-navigation
react-native-redux-router
react-native-router-redux
react-native-route-navigator
react-native-simple-router
react-native-router
react-native-router-flux
react-router-navigation
react-community/react-navigation
wix/react-native-navigation
aksonov/react-native-router-flux
react-native-router-flux
Примеры, компоненты Router & Scene
<Router>
<Scene key="root">
<Scene key="home" component={Home} title="Home" "/>
<Scene key="about" component={About} title="About" "/>
<Scene key="wrapper" hideNavBar>
{"/* Nested scenes "*/}
"</Scene>
"</Scene>
"</Router>
Примеры, использование Actions
<Router>
<Scene key="root">
<Scene key="home" component={Home} title="Home" "/>
<Scene key="about" component={About} title="About" "/>
<Scene key="wrapper" hideNavBar>
{"/* Nested scenes "*/}
"</Scene>
"</Scene>
"</Router>
class About extends React.Component {
goHome = () "=> Actions['home']()
popHome = () "=> Actions.pop()
goHomeWithParams = () "=> Actions['home']({
iWillBeAvailableThroughPropsAtHome: ‘Hi there!’
})
"/* render etc "*/
}
Примеры, вспомогательные функции
const createScene = (key, {title, ""...props}) "=>
<Scene key={key}
sceneStyle={{padding: 64}}
renderLeftButton={() "=> <MenuToggle "/>}
title={(title "|| key).toUpperCase()}
{""...props} "/>
const Scenes = (
<Scene key="drawer" component={Drawer}>
<Scene key="wrapper">
{createScene('home', {component: Home, initial: true})}
{createScene('about', {component: About})}
{createScene('logout', {component: Logout, title: 'Log Out'})}
"</Scene>
"</Scene>
)
Примеры, Drawer
import Drawer from 'react-native-drawer'
import { DefaultRenderer, Keyboard } from 'react-native-router-flux'
"/* Drawer render "*/
const {navigationState, onNavigate} = props
return (
<Drawer {""...drawerProps}
open={navigationState.isOpen}
content={<WrappedComponent "/>}
onOpenStart={Keyboard.dismissKeyboard}>
<DefaultRenderer onNavigate={onNavigate}
navigationState={navigationState.children[0]} "/>
"</Drawer>
)
Примеры, Sub-scenes
const ProfileScenes = (
<Scene key="profile" component={Profile} title="My Profile">
<Scene key="profile/view" "/>
<Scene key="profile/edit" editMode
rightTitle="Save" onRight={saveProfile}
leftTitle="Cancel" onLeft={backToViewMode} "/>
<Scene key="profile/save" save "/>
"</Scene>
)
Примеры, Switch
<Scene
key="root"
tabs={true}
unmountScenes
component={connect(state "=> ({session: getSession(state)}))(Switch)}
selector={props "=> props.session ? 'main' : 'unauthorized'}
>
<Scene key="unauthorized" component={Unauthorized} "/>
<Scene key="main" component={Main} "/>
"</Scene>
react-navigation
Примеры, StackNavigator
StackNavigator({
Home: {
screen: HomeScreen,
navigationOptions: ({navigation}) "=> ({
title: 'Home',
headerRight: <Button onClick={navigation.navigate('somewhere')} "/>,
header: <CustomHeader "/>
"/* other screen props "*/
})
},
About,
"/* other screens "*/
}, {
headerMode: 'float',
initialRouteName: 'Home'
"/* other StackNavigator props "*/
})
Примеры, TabNavigator
TabNavigator({
Home: {
screen: HomeScreen,
navigationOptions: ({navigation}) "=> ({
tabBarLabel: 'Home',
tabBarIcon: ({tintColor}) "=> <Icon tint={tintColor}"/>
})
},
Feed,
"/* other tabs "*/
}, {
tabBarComponent: TabBarBottom,
tabBarOptions: {
activeTintColor: 'teal', "/* other tabBar props "*/
},
"/* other TabNavigator props "*/
})
Примеры, DrawerNavigator
DrawerNavigator({
Home: {
screen: HomeScreen,
navigationOptions: ({navigation}) "=> ({
drawerLabel: 'Home',
drawerIcon: ({tintColor}) "=> <Icon tint={tintColor}"/>
})
},
Profile,
"/* other tabs "*/
}, {
activeTintColor: 'teal',
contentComponent: props "=>
<ScrollView><DrawerItems {""...props} "/>"</ScrollView>
"/* other DrawerNavigator props "*/
})
Примеры, nested navigators
StackNavigator({
Tabs: {
screen: TabNavigator({ "/* tabs "*/ })
},
Stack: {
screen: StackNavigator({ "/* screens "*/ })
}
})
Примеры, screen props
this.props.navigation = {
dispatch,
goBack,
navigate,
"/* few more "*/
}
NavigationActions
NavigationActions.navigate({
routeName: 'Profile',
actions: [
NavigationActions.navigate({
routeName: 'Friends',
})
]
})
Работа с данными
Redux
Getting Started with Redux Building React Applications
with Idiomatic Redux
Набор джентльмена
redux && react-redux
redux-logger / redux-devtools
ducks modular structure
redux-actions
reselect
redux-saga
redux-persist
erikras/ducks-modular-redux
import { createAction, handleActions } from 'redux-actions'
import { moduleName } from './config' // moduleName = 'todosModule'
const initialState = {todos: []}
// MAY export action type, if it should be accessible
// in other parts of the app (e.g. redux-saga or other module)
const TODO_ADD = `${moduleName}/TODO_ADD`
// MUST export creators
export const addTodo = createAction(TODO_ADD)
// MUST export reducer as default
export default handleActions({
[TODO_ADD]: (state, {payload}) => ({todos: […state, payload]})
}, initialState);
// selectors, sagas, epics etc. MAY also be named export
redux/modules/todos/index.js
import { createSelector } from 'reselect'
import { moduleName } from ‘./config'
export const getTodos = state => state[moduleName].todos
export const getVisibilityFilter = state => state[moduleName].filter
export const getVisibleTodos = createSelector(
[getTodos, getVisibilityFilter],
(todos, visibilityFilter) => {
switch (filter) {
case 'SHOW_ALL':
return todos
case 'SHOW_COMPLETED':
return todos.filter(todo => todo.completed)
case 'SHOW_ACTIVE':
return todos.filter(todo => !todo.completed)
}
}
)
// todoList.js | import * as todosSelectors from '@modules/todos/selectors'
redux/modules/todos/selectors.jsreactjs/reselect
redux-thunk
redux-loop
redux-observable
5,402
1,214
2,992
8,129
Сайд-эффекты в Redux
redux-saga
Redux-Thunk
const a = <div onClick={
() => dispatch(actions.loadUser(userId))
}>{username}</div>
export const loadUser = userId =>
async dispatch => {
try {
const user = await userService.load(userId)
dispatch(userLoaded(user))
} catch (err) {
dispatch(userLoadFailed(err))
}
}
const a = <div onClick={
() => dispatch(actions.userNameClicked(userId))
}>{username}</div>
function * watchUserNameClickAndLoad () {
yield * takeLatest(USER_NAME_CLICKED, loadUser)
}
function * loadUser ({payload}) {
try {
const user = yield call(userService.load, payload)
yield put(userLoaded(user))
}
catch (err) {
yield put(userLoadFailed(err))
}
}
Императивный flow
+
Декларативные сайд-эффекты
+
Мощь генераторов
+
Огромное кол-во хелперов
Хелперы / Эффекты
• take (watcher)
• takeLatest (cancels previous)
• takeEvery
• call (blocking)
• fork (non-blocking)
• put (saga dispatch)
• select (saga mapState)
• delay
• cancel
• race && all (like in Promises)
etc.
redux-saga: login flow example
function * authorization () {
// Check the storage for cached token and profile
let [token, profile] = yield [
call(auth.getToken),
call(auth.getProfile),
]
// so now user may be logged in...
}
redux-saga: login flow example
// ...or may not, so we gonna wait for it
if (!token) {
const {payload: credentials} = yield take(profileActions.SIGN_IN)
const {response, error} = yield call(authRequest, credentials)
if (error) {
yield put(profileActions.signInFailed(error))
continue
}
token = response.token
profile = response.profile
yield [
call(auth.setToken, token),
call(auth.setProfile, profile),
]
}
redux-saga: login flow example
// Now when we have token and profile
// We can let user in
yield put(profileActions.signInSuccess({token, profile}))
yield take(profileActions.SIGN_OUT)
token = profile = null
yield [
call(auth.removeToken),
call(auth.removeProfile),
]
yield put(stackActions.clear())
yield put(profileActions.signOutSuccess())
redux-saga: login flow example
function * authorization () {
// Check the storage for cached token and profile
let [token, profile] = yield [call(auth.getToken), call(auth.getProfile)]
while (true) {
if (!token) {…} /* Receive token and profile data */
yield put(profileActions.signInSuccess({token, profile}))
yield take(profileActions.SIGN_OUT)
/* Other signOut stuff */
}
}
Ignite
https://infinite.red/ignite
Заходите на Medium
Twitter
@reactjs @reactnative @dan_abramov@Vjeux
@JI @grabbou @tylermcginnis33 @koltal
По максимуму используйте PropTypes и DefaultProps
Для клавиатуры используйте KeyboardAvoidingView
Внимательно изучайте документацию
Не пренебрегайте селекторами
Найдите в себе силы разобраться с Redux-Saga - не пожалеете
Не забывайте убивать console.log, когда льете в прод
И конечно же пишите на React Native - он крутой
inline-советы напоследок
Вопросы?
linkedin.com/in/drukas16

Más contenido relacionado

La actualidad más candente

Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"
Fwdays
 

La actualidad más candente (20)

Introduction to React Native Workshop
Introduction to React Native WorkshopIntroduction to React Native Workshop
Introduction to React Native Workshop
 
Hands on react native
Hands on react nativeHands on react native
Hands on react native
 
An Overview of the React Ecosystem
An Overview of the React EcosystemAn Overview of the React Ecosystem
An Overview of the React Ecosystem
 
Ryan Christiani I Heard React Was Good
Ryan Christiani I Heard React Was GoodRyan Christiani I Heard React Was Good
Ryan Christiani I Heard React Was Good
 
Introduction to react native
Introduction to react nativeIntroduction to react native
Introduction to react native
 
React Native for ReactJS Devs
React Native for ReactJS DevsReact Native for ReactJS Devs
React Native for ReactJS Devs
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React Native
 
React Native custom components
React Native custom componentsReact Native custom components
React Native custom components
 
Creating books app with react native
Creating books app with react nativeCreating books app with react native
Creating books app with react native
 
Intro To React Native
Intro To React NativeIntro To React Native
Intro To React Native
 
Optimizing React Native views for pre-animation
Optimizing React Native views for pre-animationOptimizing React Native views for pre-animation
Optimizing React Native views for pre-animation
 
React Native: React Meetup 3
React Native: React Meetup 3React Native: React Meetup 3
React Native: React Meetup 3
 
Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"
 
React Native: Introduction
React Native: IntroductionReact Native: Introduction
React Native: Introduction
 
From zero to hero with React Native!
From zero to hero with React Native!From zero to hero with React Native!
From zero to hero with React Native!
 
React Native "A Bad Idea Or A Game Changer" at Code Mania 101
React Native "A Bad Idea Or A Game Changer" at Code Mania 101React Native "A Bad Idea Or A Game Changer" at Code Mania 101
React Native "A Bad Idea Or A Game Changer" at Code Mania 101
 
What's This React Native Thing I Keep Hearing About?
What's This React Native Thing I Keep Hearing About?What's This React Native Thing I Keep Hearing About?
What's This React Native Thing I Keep Hearing About?
 
Putting the Native in React Native - React Native Boston
Putting the Native in React Native - React Native BostonPutting the Native in React Native - React Native Boston
Putting the Native in React Native - React Native Boston
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
 
Getting Started with React-Nathan Smith
Getting Started with React-Nathan SmithGetting Started with React-Nathan Smith
Getting Started with React-Nathan Smith
 

Similar a How to React Native

JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
Nick Sieger
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
Andy Peterson
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
Aaronius
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha
 

Similar a How to React Native (20)

Connect.js - Exploring React.Native
Connect.js - Exploring React.NativeConnect.js - Exploring React.Native
Connect.js - Exploring React.Native
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
React on Rails - RailsConf 2017 (Phoenix)
 React on Rails - RailsConf 2017 (Phoenix) React on Rails - RailsConf 2017 (Phoenix)
React on Rails - RailsConf 2017 (Phoenix)
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
 
Heroku pop-behind-the-sense
Heroku pop-behind-the-senseHeroku pop-behind-the-sense
Heroku pop-behind-the-sense
 
An Emoji Introduction to React Native (Panagiotis Vourtsis, Senior Front End ...
An Emoji Introduction to React Native (Panagiotis Vourtsis, Senior Front End ...An Emoji Introduction to React Native (Panagiotis Vourtsis, Senior Front End ...
An Emoji Introduction to React Native (Panagiotis Vourtsis, Senior Front End ...
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAE
 
React native by example by Vadim Ruban
React native by example by Vadim RubanReact native by example by Vadim Ruban
React native by example by Vadim Ruban
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
 
WordPress as the Backbone(.js)
WordPress as the Backbone(.js)WordPress as the Backbone(.js)
WordPress as the Backbone(.js)
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
 
Let's react - Meetup
Let's react - MeetupLet's react - Meetup
Let's react - Meetup
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 

Último

Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven CuriosityUnlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
Hung Le
 
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
ZurliaSoop
 
Uncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac FolorunsoUncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac Folorunso
Kayode Fayemi
 
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
David Celestin
 
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
amilabibi1
 

Último (17)

Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven CuriosityUnlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
 
lONG QUESTION ANSWER PAKISTAN STUDIES10.
lONG QUESTION ANSWER PAKISTAN STUDIES10.lONG QUESTION ANSWER PAKISTAN STUDIES10.
lONG QUESTION ANSWER PAKISTAN STUDIES10.
 
Introduction to Artificial intelligence.
Introduction to Artificial intelligence.Introduction to Artificial intelligence.
Introduction to Artificial intelligence.
 
SOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdf
SOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdfSOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdf
SOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdf
 
in kuwait௹+918133066128....) @abortion pills for sale in Kuwait City
in kuwait௹+918133066128....) @abortion pills for sale in Kuwait Cityin kuwait௹+918133066128....) @abortion pills for sale in Kuwait City
in kuwait௹+918133066128....) @abortion pills for sale in Kuwait City
 
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
 
Dreaming Music Video Treatment _ Project & Portfolio III
Dreaming Music Video Treatment _ Project & Portfolio IIIDreaming Music Video Treatment _ Project & Portfolio III
Dreaming Music Video Treatment _ Project & Portfolio III
 
Uncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac FolorunsoUncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac Folorunso
 
My Presentation "In Your Hands" by Halle Bailey
My Presentation "In Your Hands" by Halle BaileyMy Presentation "In Your Hands" by Halle Bailey
My Presentation "In Your Hands" by Halle Bailey
 
Dreaming Marissa Sánchez Music Video Treatment
Dreaming Marissa Sánchez Music Video TreatmentDreaming Marissa Sánchez Music Video Treatment
Dreaming Marissa Sánchez Music Video Treatment
 
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
 
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdfAWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
 
ICT role in 21st century education and it's challenges.pdf
ICT role in 21st century education and it's challenges.pdfICT role in 21st century education and it's challenges.pdf
ICT role in 21st century education and it's challenges.pdf
 
Zone Chairperson Role and Responsibilities New updated.pptx
Zone Chairperson Role and Responsibilities New updated.pptxZone Chairperson Role and Responsibilities New updated.pptx
Zone Chairperson Role and Responsibilities New updated.pptx
 
Report Writing Webinar Training
Report Writing Webinar TrainingReport Writing Webinar Training
Report Writing Webinar Training
 
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
 
Digital collaboration with Microsoft 365 as extension of Drupal
Digital collaboration with Microsoft 365 as extension of DrupalDigital collaboration with Microsoft 365 as extension of Drupal
Digital collaboration with Microsoft 365 as extension of Drupal
 

How to React Native

  • 1. How to React Native
  • 3. 2 проекта 10 месяцев 2-3 JS разработчика 1 нативный разработчик
  • 8. React - это reconciler
  • 9. ReactDOM - это renderer
  • 10. React Native - тоже renderer
  • 12. JS Движок JavaScript Core. Babel под капотом и свой react-native пресет Поддержка ES6 и ES7 фич Полифиллы для ES6-ES7 методов Object, Array и String; а также для XMLHttpRequest, fetch, консоли, тайм-аутов и тд.
  • 14. Create React Native App expo.io
  • 15.
  • 17. components/text/styles.js import { StyleSheet } from 'react-native' import * as Styles from '@styles' export default StyleSheet.create({ default: { fontSize: Styles.fontSizes.normal, fontFamily: Styles.fonts.primaryFont, color: Styles.colors.dark, }, bold: { fontWeight: ‘bold’ }, "/* other styles "*/ })
  • 18. import { create } from ‘react-native-platform-stylesheet' export default create({ default: { fontSize: 18, ios: { fontFamily: 'Helvetica' }, android: { fontFamily: 'Roboto' } } }) components/text/styles.js, платформозависимый код
  • 19. import { create } from ‘react-native-platform-stylesheet' export default create({ default: { fontSize: 18, ios: { fontFamily: 'Helvetica' }, android: { fontFamily: 'Roboto' } } }) components/text/styles.js, платформозависимый код
  • 20. { "/* ""... "*/ "rnpm": { "assets": [ "fonts" ] } } Кладем свои шрифты в fonts/ и обновляем package.json $ react-native link assets 🎉🎉🎉🎉🎉
  • 21. import styles from './styles.js' const Text = ({children, ""...props}) !=> { const { bold, color, style: styleExtension, ""...otherProps } = props const style = [ styles.default, styleExtension, bold !&& styles.bold, color !&& { color }, ] return ( <RNText {""...otherProps} style={style}> {children} "</RNText> ) } components/text/index.js, теперь со стилями
  • 22. import styles from './styles.js' const Text = ({children, ""...props}) !=> { const { bold, color, style: styleExtension, ""...otherProps } = props const style = [ styles.default, styleExtension, bold !&& styles.bold, color !&& { color }, ] return ( <RNText {""...otherProps} style={style}> {children} "</RNText> ) } components/text/index.js, теперь со стилями
  • 23. Использование компонента Text <View> <Text>Default text!"</Text> <Text bold>Bold text!"</Text> <Text color=“teal”> Colored text! "</Text> "</View>
  • 24. Использование компонента Text <View> <Text>Default text!"</Text> <Text bold>Bold text!"</Text> <Text color=“teal”> Colored text! "</Text> "</View>
  • 25. import Color from 'color' const teal = Color('teal') const gray = Color('dimgray') const darker = color !=> color.darken(0.25) const withOpacity = color !=> color.alpha(0.8) export default { dark: gray, darker: darker(gray), primary: teal, primaryWithOpacity: withOpacity(teal), } styles/colors.js, используем npm модуль color
  • 26. Платформозависимый код const OS = Platform.OS "// 'android' or 'ios' const platform = Platform.select({ ios: 'ios', android: 'android' }) ├── filename.js "// кросплатформенный файл ├── filename.ios.js "// iOS └── filename.android.js "// Android
  • 29. • MRN • React Native Material Design • React Native Material Kit
  • 31. Animated API LayoutAnimation API class SpinningImage extends React.Component { spinValue = new Animated.Value(0) componentDidMount() { this.spin() } spin = () => { this.spinValue.setValue(0) Animated.timing(this.spinValue, { toValue: 1, duration: 2000, easing: Easing.linear, useNativeDriver: true, }).start(this.spin) } render() { const spin = this.spinValue.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] }) const transform = [{rotate: spin}] const style = [styles.image, {transform}] return ( <View> <Animated.Image style={style} source={myImage}/> </View> ) } } if (Platform.OS === 'android') { UIManager.setLayoutAnimationEnabledExperimental(true); } class BoxWithSizeChanges extends React.Component { state = {size: 200} increaseSize = () => { LayoutAnimation.spring() // OR LayoutAnimation.configureNext(CUSTOM_CONFIG) this.setState(state => ({size: state.size + 50})) } render() { const {size} = this.state const sizes = {height: size, width: size} const style = [styles.box, sizes] return ( <View> <Box style={style}/> <Button onPress={this.increaseSize} title=‘Make him bigger!’/> </View> ) } }
  • 33. Real World React Native Animations
  • 34. oblador/react-native-animatable <Animatable.Text animation="slideInDown" iterationCount={5} direction="alternate"> Up and down you go </Animatable.Text> <Animatable.Text animation="pulse" easing="ease-out" iterationCount="infinite" style={{textAlign: 'center'}}> ❤ </Animatable.Text>
  • 36. React Native решения “из коробки” NavigatorIOS Navigator NavigationExperimental
  • 37. React Native решения “из коробки” NavigatorIOS Navigator NavigationExperimental
  • 41. Примеры, компоненты Router & Scene <Router> <Scene key="root"> <Scene key="home" component={Home} title="Home" "/> <Scene key="about" component={About} title="About" "/> <Scene key="wrapper" hideNavBar> {"/* Nested scenes "*/} "</Scene> "</Scene> "</Router>
  • 42. Примеры, использование Actions <Router> <Scene key="root"> <Scene key="home" component={Home} title="Home" "/> <Scene key="about" component={About} title="About" "/> <Scene key="wrapper" hideNavBar> {"/* Nested scenes "*/} "</Scene> "</Scene> "</Router> class About extends React.Component { goHome = () "=> Actions['home']() popHome = () "=> Actions.pop() goHomeWithParams = () "=> Actions['home']({ iWillBeAvailableThroughPropsAtHome: ‘Hi there!’ }) "/* render etc "*/ }
  • 43. Примеры, вспомогательные функции const createScene = (key, {title, ""...props}) "=> <Scene key={key} sceneStyle={{padding: 64}} renderLeftButton={() "=> <MenuToggle "/>} title={(title "|| key).toUpperCase()} {""...props} "/> const Scenes = ( <Scene key="drawer" component={Drawer}> <Scene key="wrapper"> {createScene('home', {component: Home, initial: true})} {createScene('about', {component: About})} {createScene('logout', {component: Logout, title: 'Log Out'})} "</Scene> "</Scene> )
  • 44. Примеры, Drawer import Drawer from 'react-native-drawer' import { DefaultRenderer, Keyboard } from 'react-native-router-flux' "/* Drawer render "*/ const {navigationState, onNavigate} = props return ( <Drawer {""...drawerProps} open={navigationState.isOpen} content={<WrappedComponent "/>} onOpenStart={Keyboard.dismissKeyboard}> <DefaultRenderer onNavigate={onNavigate} navigationState={navigationState.children[0]} "/> "</Drawer> )
  • 45. Примеры, Sub-scenes const ProfileScenes = ( <Scene key="profile" component={Profile} title="My Profile"> <Scene key="profile/view" "/> <Scene key="profile/edit" editMode rightTitle="Save" onRight={saveProfile} leftTitle="Cancel" onLeft={backToViewMode} "/> <Scene key="profile/save" save "/> "</Scene> ) Примеры, Switch <Scene key="root" tabs={true} unmountScenes component={connect(state "=> ({session: getSession(state)}))(Switch)} selector={props "=> props.session ? 'main' : 'unauthorized'} > <Scene key="unauthorized" component={Unauthorized} "/> <Scene key="main" component={Main} "/> "</Scene>
  • 47. Примеры, StackNavigator StackNavigator({ Home: { screen: HomeScreen, navigationOptions: ({navigation}) "=> ({ title: 'Home', headerRight: <Button onClick={navigation.navigate('somewhere')} "/>, header: <CustomHeader "/> "/* other screen props "*/ }) }, About, "/* other screens "*/ }, { headerMode: 'float', initialRouteName: 'Home' "/* other StackNavigator props "*/ })
  • 48. Примеры, TabNavigator TabNavigator({ Home: { screen: HomeScreen, navigationOptions: ({navigation}) "=> ({ tabBarLabel: 'Home', tabBarIcon: ({tintColor}) "=> <Icon tint={tintColor}"/> }) }, Feed, "/* other tabs "*/ }, { tabBarComponent: TabBarBottom, tabBarOptions: { activeTintColor: 'teal', "/* other tabBar props "*/ }, "/* other TabNavigator props "*/ })
  • 49. Примеры, DrawerNavigator DrawerNavigator({ Home: { screen: HomeScreen, navigationOptions: ({navigation}) "=> ({ drawerLabel: 'Home', drawerIcon: ({tintColor}) "=> <Icon tint={tintColor}"/> }) }, Profile, "/* other tabs "*/ }, { activeTintColor: 'teal', contentComponent: props "=> <ScrollView><DrawerItems {""...props} "/>"</ScrollView> "/* other DrawerNavigator props "*/ })
  • 50. Примеры, nested navigators StackNavigator({ Tabs: { screen: TabNavigator({ "/* tabs "*/ }) }, Stack: { screen: StackNavigator({ "/* screens "*/ }) } })
  • 51. Примеры, screen props this.props.navigation = { dispatch, goBack, navigate, "/* few more "*/ } NavigationActions NavigationActions.navigate({ routeName: 'Profile', actions: [ NavigationActions.navigate({ routeName: 'Friends', }) ] })
  • 53. Redux
  • 54. Getting Started with Redux Building React Applications with Idiomatic Redux
  • 55. Набор джентльмена redux && react-redux redux-logger / redux-devtools ducks modular structure redux-actions reselect redux-saga redux-persist
  • 56. erikras/ducks-modular-redux import { createAction, handleActions } from 'redux-actions' import { moduleName } from './config' // moduleName = 'todosModule' const initialState = {todos: []} // MAY export action type, if it should be accessible // in other parts of the app (e.g. redux-saga or other module) const TODO_ADD = `${moduleName}/TODO_ADD` // MUST export creators export const addTodo = createAction(TODO_ADD) // MUST export reducer as default export default handleActions({ [TODO_ADD]: (state, {payload}) => ({todos: […state, payload]}) }, initialState); // selectors, sagas, epics etc. MAY also be named export redux/modules/todos/index.js
  • 57. import { createSelector } from 'reselect' import { moduleName } from ‘./config' export const getTodos = state => state[moduleName].todos export const getVisibilityFilter = state => state[moduleName].filter export const getVisibleTodos = createSelector( [getTodos, getVisibilityFilter], (todos, visibilityFilter) => { switch (filter) { case 'SHOW_ALL': return todos case 'SHOW_COMPLETED': return todos.filter(todo => todo.completed) case 'SHOW_ACTIVE': return todos.filter(todo => !todo.completed) } } ) // todoList.js | import * as todosSelectors from '@modules/todos/selectors' redux/modules/todos/selectors.jsreactjs/reselect
  • 59. Redux-Thunk const a = <div onClick={ () => dispatch(actions.loadUser(userId)) }>{username}</div> export const loadUser = userId => async dispatch => { try { const user = await userService.load(userId) dispatch(userLoaded(user)) } catch (err) { dispatch(userLoadFailed(err)) } } const a = <div onClick={ () => dispatch(actions.userNameClicked(userId)) }>{username}</div> function * watchUserNameClickAndLoad () { yield * takeLatest(USER_NAME_CLICKED, loadUser) } function * loadUser ({payload}) { try { const user = yield call(userService.load, payload) yield put(userLoaded(user)) } catch (err) { yield put(userLoadFailed(err)) } }
  • 60. Императивный flow + Декларативные сайд-эффекты + Мощь генераторов + Огромное кол-во хелперов
  • 61. Хелперы / Эффекты • take (watcher) • takeLatest (cancels previous) • takeEvery • call (blocking) • fork (non-blocking) • put (saga dispatch) • select (saga mapState) • delay • cancel • race && all (like in Promises) etc.
  • 62. redux-saga: login flow example function * authorization () { // Check the storage for cached token and profile let [token, profile] = yield [ call(auth.getToken), call(auth.getProfile), ] // so now user may be logged in... }
  • 63. redux-saga: login flow example // ...or may not, so we gonna wait for it if (!token) { const {payload: credentials} = yield take(profileActions.SIGN_IN) const {response, error} = yield call(authRequest, credentials) if (error) { yield put(profileActions.signInFailed(error)) continue } token = response.token profile = response.profile yield [ call(auth.setToken, token), call(auth.setProfile, profile), ] }
  • 64. redux-saga: login flow example // Now when we have token and profile // We can let user in yield put(profileActions.signInSuccess({token, profile})) yield take(profileActions.SIGN_OUT) token = profile = null yield [ call(auth.removeToken), call(auth.removeProfile), ] yield put(stackActions.clear()) yield put(profileActions.signOutSuccess())
  • 65. redux-saga: login flow example function * authorization () { // Check the storage for cached token and profile let [token, profile] = yield [call(auth.getToken), call(auth.getProfile)] while (true) { if (!token) {…} /* Receive token and profile data */ yield put(profileActions.signInSuccess({token, profile})) yield take(profileActions.SIGN_OUT) /* Other signOut stuff */ } }
  • 69. Twitter @reactjs @reactnative @dan_abramov@Vjeux @JI @grabbou @tylermcginnis33 @koltal
  • 70. По максимуму используйте PropTypes и DefaultProps Для клавиатуры используйте KeyboardAvoidingView Внимательно изучайте документацию Не пренебрегайте селекторами Найдите в себе силы разобраться с Redux-Saga - не пожалеете Не забывайте убивать console.log, когда льете в прод И конечно же пишите на React Native - он крутой inline-советы напоследок