class: front-page # React Native ## Workshop JavaZone 06.09.2016 --- class: agenda # Agenda * Intro * Syntax and styling * Redux * Navigation * Instant deploy? * You're next! ??? ## Some topics that will prepare you for the assignments ## Before I start. Who are familiar with React, RN, Redux? ## I will not go deep into the inner workings of RN, but I will do this quick, so you get more time coding. But you are free to use these slides as reference during the coding as well. --- # Intro - Native ## Released for iOS January 2015 og for Android in september, by Facebook ## As of April 2016, also for Windows (UWP) ## Open Source ## Problems with (traditional) native - Slow development cycle - Slow deployment process - Separate teams for each platform ??? ## Facebook uses React Native in multiple production apps and and they have stated that they will continue investing in React Native. ## During this years F8-conference by Facebook Windows support was annouced. Can use RN-components in UWP-apps. Supported in Visual Studio Code ## Already a big community. Provides PR and creates React components. ## Frequent releases. Always several new versions between each time we work on this workshop. ## Didn't work to wrap webapps anymore. The web isn't ready for it, yet. ## Can do lots of cool things with native, but they thought that the development was to slow with native. The development environment was slower. Could take a minute or more to recompile and deploy, and watch the changes in the app. ## Developers need to learn several languages, apis and tools. It was not as lean as they were used to from the web and with react.. And business logic had to be developed at least twice. For iOS and Android. --- # Intro - Cross platform ## Problems with cross platform - Bad performance - Not (always) native look & feel - The tooling and debugging is not as good as in native development - Limited functionality ??? ## Cross platform, wrapped web pages etc. ## Facebook has tried the most of it. And for a while the app was just a wrapped WebView. With poor performance. ## Not the native experience ## But the web has solved a lot of problems that are present in native and cross platform development, so they wanted to build on that. But the web isn't ready to replace native yet. ## So what we want is the native experience, with the developer experience from the web --- # What is React Native? ## Build on React.js ## Same principles, with virtual DOM ## Web-DOM is replaced with native components ## _Learn_ once, write anywhere ??? ## Modules, virtual DOM og declarative API. We describes what the program should render, not how. ## Doesn't have to render to the DOM, since the view system is separated from the view implementation. ## Apparent in new version of React.js. where React and ReactDOM is separated. ## NOT write once. But it is encouraging reuse. F.eks APIS, events, business-logic. But not necessarily view-code. ## Should be familiar to developers coming from JS and React. ## Can reuse components from the web, and in addition get access to platform components. ## So in many cases it is npm install, and you're good to go --- # Much like React.js 1/2 ```html
Hello world
Click me!
``` ```html
Hello world
Click me!
``` ??? ## Much like React.js, but you can't copy paste your React.js app and call it the day. ## But it is still JSX ## Button --- # Much like React.js 2/2 ```html
this.setState({text})} /> ``` ```html
this.setState({text})} /> ``` ## Some are platform specific: ```html
``` ??? ## Input ## React-Native uses "Controlled Components", so there is a 'value' prop --- class: cols two # Components .col[ ## The most common components and APIs are available ## You can write your own modules in native code, and expose ## Many components from the community are available as npm modules ] .col[ .small-img[![](img/ReactComponents.png)] ] ??? ## As with other platforms there will be a delay between a new feature in the platforms and implementation in RN, but are available as npm modules --- # Not a web app! ## Is not a React-js app wrapped in a WebView ## Proper native platform components ## Optimizations - JS runs on JavaScriptCore - JS runs asyncronous, separated from the UI thread. - JS to Native via "bridge". ??? ## That it is based on React.js does not mean that is is a React.JS app wrapped in a WebView ## As I said earlier, the DOM is interchanged. ## Not WebView, so it feels native. Parts of the Facebook app is actually RM. That is the Events part of the app. ## Sends batched commands to the UI thread. ## Multiple threads, as opposed to the web. Decode images, save to disc, do layout measurements can be done outside of the UI thead => Responsive app. ## The stated goal for Facebook has been 60 fps, for a snappy UI --- # Bridge .col[ .full-img[![](img/ReactBridge.png)] ] ??? ## Receives an input, click. ## Gathers information, serialize it to JSON, and sends it to JSCore. ## JS processes events and creates a list of native commands. ## This is serialized and sent back to Native. ## Processes commands and updates UI https://speakerdeck.com/frantic/react-native-under-the-hood --- #What do you need? * XCode * Android-SDK * Node 4.x * npm 3 * react-native-cli * Your favorite editor/IDE ??? ## Sublime, Atom, Nuclide, IntelliJ etc --- class: cols two # Development environment! .col[ ## React Native ships with a Packager ## Updates with ⌘-R ## Debugging in Chrome. ⌘-D (iOS) / F2(Android) ## Descriptive and in-your-face error messages ] .col[ .small-img[![](img/ReactNative4.png)] ] ??? ## Packager builds the app, and is running in the background waiting for changes. ## A common obstacle in native development is the environment. Many people are not comfortable with XCode. ## Can run in Chromes V8 (communicates with native via WebSockets) and use the normal Chrome debugger like you're used to ## Of you are developing on a device, you can shake it to access developer options. --- # Styling - Known from CSS ## "Inline styles" ## camelCasing ## margin, marginBottom, paddingBottom, borderRadius, width, height ## backgroundColor, borderColor, fontSize, fontWeight ```html
Welcome to JavaZone workshop
``` ??? ## A javascript-implementation of CSS ## Most of the common CSS-props are implemented ## Inline styles with JS-objects --- # Styling - FLEXBOX ## Flexbox is used to lay out components ## Based on Flexbox from css ## flex direction, flex, align items, align self, justify content, ... ??? ## A javascript-implementation of Flexbox. Based on CSS standards ## So you have containers who specifies child nodes, and you lay out in either columns or rows. ## I will demonstrate this quick, and the slides are more of a reference for you guys when implementing the tasks. And links to more documentation is provided along with the tasks. --- class: cols two # FLEXBOX - direction ## flexDirection: column (default) .col[ ```javascript class Flexbox extends Component { render() { return (
); } } ``` ] .col[ .small-img[![](img/flex_column.png)] ] ??? ## Along which axis the child nodes are laid out ## Column: top to bottom --- class: cols two # FLEXBOX - direction ## flexDirection: row .col[ ```javascript class Flexbox extends Component { render() { return (
); } } ``` ] .col[ .small-img[![](img/flex_row.png)] ] ??? ## Left to right in a row --- class: cols two # FLEXBOX - justify content ## justifyContent: flex-start (default) .col[ ```html
Hello
Hello
Hello
``` ] .col[ .small-img[![](img/justifyContent_flexStart.png)] ] ??? ## This defines the alignment along the main axis ## How elements are laid out inside of the container ## This refers to the child elements --- class: cols two # FLEXBOX - justify content ## justifyContent: center .col[ ```html
Hello
Hello
Hello
``` ] .col[ .small-img[![](img/justifyContent_center.png)] ] --- class: cols two # FLEXBOX - justify content ## justifyContent: flex-end .col[ ```html
Hello
Hello
Hello
``` ] .col[ .small-img[![](img/justifyContent_flexEnd.png)] ] --- class: cols two # FLEXBOX - justify content ## justifyContent: space-around .col[ ```html
Hello
Hello
Hello
``` ] .col[ .small-img[![](img/justifyContent_spaceAround.png)] ] --- class: cols two # FLEXBOX - justify content ## justifyContent: space-between .col[ ```html
Hello
Hello
Hello
``` ] .col[ .small-img[![](img/justifyContent_spaceBetween.png)] ] --- class: cols two # FLEXBOX - align items ## align-items: stretch (default) .col[ ```html
Hello
Hello
Hello
``` ] .col[ .small-img[![](img/alignItems_stretch.png)] ] ??? ## This defines the alignment across the main axis ## Also for child nodes. Equivalent for elements is alignSelf --- class: cols two # FLEXBOX - align items ## align-items: flex-start .col[ ```html
Hello
Hello
Hello
``` ] .col[ .small-img[![](img/alignItems_flexStart.png)] ] --- class: cols two # FLEXBOX - align items ## align-items: flex-end .col[ ```html
Hello
Hello
Hello
``` ] .col[ .small-img[![](img/alignItems_flexEnd.png)] ] --- class: cols two # FLEXBOX - align items ## align-items: center .col[ ```html
Hello
Hello
Hello
``` ] .col[ .small-img[![](img/alignItems_center.png)] ] --- class: cols two # FLEXBOX - flex ## flex: 1, flex: 1 .col[ ```html
``` ] .col[ .small-img[![](img/flex_1_1.png)] ] ??? ## How much space should the element get? ## If all have the same value, the get the same amount of space ## 0 => As much space as the element needs ## >0 As much space as possible --- class: cols two # FLEXBOX - flex ## flex: 2, flex: 1 .col[ ```html
``` ] .col[ .small-img[![](img/flex_2_1.png)] ] --- class: cols two # Style objects ## Common to extract into style objects .col[ ```html
Hello world!!
Welcome to JavaZone workshop
``` ] .col[ ```javascript var styles = StyleSheet.create({ row: { flexDirection: 'row', margin: 40 }, image: { width: 40, height: 40, marginRight: 10 }, text: { flex: 1, justifyContent: 'center'}, title: { fontSize: 11, fontWeight: 'bold' }, subtitle: { fontSize: 10 }, }); ``` ] --- # FLEXBOX ## Can have multiple "classes" ```html
``` ## And conditional classes ```html
``` ??? ## Export modules, f.eks. base-styling --- # State/Redux ## A simplified implementation of Flux ## Single store ## Actions - describes the change of state ## Reducers - returns new state based on action ??? ## State container. One of the great things with RN. You can reuse modules and concepts from the web. ## 3 principles ## Single source of truth - One single store ## State is read-only - The only way to change the state is to emit an action, an object describing what happened. ## Changes are made with pure functions - To specify how the state tree is transformed by actions, you write pure reducers. --- # State/Redux - Single store ## app.js ```javascript import { createStore } from 'redux'; import { Provider } from 'react-redux'; import rnWorkshop from './reducers/reducers'; const store = createStore(rnWorkshop);
....
``` ??? # Views listens to the state --- # State/Redux - Actions ## actions.js ```javascript export const setUsername = username => ({ type: SET_USER_NAME, username }); ``` ## someComponent.js ```javascript import { setUsername } from '../actions/actions'; ... store.dispatch(setUsername("Mark Z.")); ... ``` ??? ## What did happen? --- # State/Redux - Reducers ## reducer.js ```javascript function messageReducer(state = initialState, action) { switch (action.type) { case SET_USER_NAME: return Object.assign({}, state, { username: action.username }); } } ``` ??? ## Reducer is a mapping between action and state. Returns next state ## Do not mutate state. Return new state. --- # They haven't nailed everything ... ## Navigator, NavigatorIOS, NavigatorExperimental, WTF? ??? ## Navigator: Unclear API, and not documented best practices. (NavigationBar in one example) - Not as smooth animations ## NavigatorIOS: Limited API, and not supported og developed by Facebook ## NavigatorExperimental: New. Facebook is transitioning from Navigator to NavigationExperimental, which will be the supported navigation library going forward. New approach to Navigation. But, as it states, it is still experimental. --- # How to use Navigator ## Important functions: `initialRoute` - starting point for Navigator `renderScene` - describe how a scene is to be rendered based on active route `push(route)` - navigate to a new page/component ??? ## Route object that identifies a page --- # How to use Navigator ## We have wrapped Navigation to abstract parts of the functionality and difficulties using it ## Init (app.js): ``` import Navigator from './components/navigation/navigator';
``` ## Use: ``` import { navigateTo } from '../actions/actions'; import NewMessage from '../new-message'; dispatch(navigateTo({component: NewMessage, title: 'Compose message'}); ``` ??? ## Uses Navigator, but have abstracted setup of Navigator and NavigationBar ## Important functions, transitions + config for look and feel (animations, navigation bar layout) ## Use: Navigator is in Redux State, so send a component into the navigateTo action. ## Uses Babel, so ES6/7 can be used --- # Instant deploy of JS? ## AppHub, CodePush (MS) ## According to the Apple guidelines > ... The only exceptions to the foregoing are scripts and code downloaded and run by Apple's built-in WebKit framework or JavascriptCore, provided that such scripts and code do not change the primary purpose of the Application ... .small-img[![](img/AppHub3.png)] ??? ## I said something about slow deployment process in the intro. ## Runs on JSC, so according to guidelines the app can be changed after release. ## If it is only JS changes, these can be pushed outside App Store. I can also be release to a subset of users for testing. --- class: middle center # YOU ARE NEXT! --- # Links ## https://facebook.github.io/react-native/docs/getting-started.html ## https://github.com/bekk/react-native-workshop