Guest User

Untitled

a guest
Sep 27th, 2018
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.39 KB | None | 0 0
  1. Here demonstrated some code sample for user login flow. Try to get core part explained, some details are omitted for easy understanding.
  2.  
  3. Some of the main dependencies:
  4. ```
  5. "flux": "^2.1.1",
  6. "react": "^16.0.0",
  7. "react-native": "^0.50.4",
  8. "react-native-navigation": "^1.1.251",
  9. "react-native-fbsdk": "^0.6.3",
  10. "react-native-image-picker": "^0.26.7",
  11. "react-native-maps": "^0.17.0",
  12. ```
  13.  
  14. **LoginScreen.js**
  15. ```js
  16. import React, { Component } from 'react';
  17. import {
  18. Alert,
  19. StyleSheet,
  20. View,
  21. ScrollView,
  22. Text,
  23. TextInput,
  24. } from 'react-native';
  25.  
  26. // Encapsulate functions to trigger async actions related to user onboarding
  27. import * as UserActionCreators from '../actions/UserActionCreators';
  28.  
  29. // see usage in render
  30. import CustomTextInput from '../comp/CustomTextInput';
  31. // ThemedButton is used across app to provide consistent style
  32. // Also it contains a flipped style to reflect which mode it is in
  33. import ThemedButton from '../comp/ThemedButton';
  34.  
  35. // SessionStore is singleton obtained from SharedServices, it basically check
  36. // if there is store instance created, return it. We can see SessionStore below
  37. const SessionStore = SharedServices.sessionStore;
  38.  
  39. class LoginScreen extends Component {
  40.  
  41. constructor(props) {
  42. super(props);
  43. this.state = {
  44. username: '', password: ''
  45. }
  46. }
  47.  
  48. componentDidMount() {
  49. // subscribe to SessionStore
  50. this._sessionListener = SessionStore.addListener(this._onStoreChange)
  51. }
  52.  
  53. componentWillUnmount() {
  54. this._sessionListener && this._sessionListener.remove();
  55. }
  56.  
  57. _onStoreChange() {
  58. // get notified in different phase of request
  59. if (SessionStore.pending === true) return;
  60.  
  61. if (SessionStore.error) {
  62. Alert.alert('Error', SessionStore.error);
  63. return;
  64. }
  65. if (SessionStore.ready) {
  66. // this screen registered with navigation, will be passed with navigator
  67. this.props.navigator.pop();
  68. }
  69. }
  70.  
  71. handleInputChange(k, v) {
  72. this.setState({[k]: v})
  73. }
  74.  
  75. renderLoginBtn() {
  76. return (
  77. <ThemedButton onPress={this._doLogin>
  78. <Icon name='ios-mail' size={24} />
  79. <Text> Log in with Email </Text>
  80. </ThemedButton>
  81. )
  82. }
  83.  
  84. _doLogin = () => {
  85. const {username, password} = this.state;
  86. // check input validation status, trigger action if all good
  87. return UserActionCreators.requestLoginWithEmail(username, password)
  88. }
  89.  
  90. render() {
  91. return (
  92. <ScrollView >
  93. // CustomTextInput can be equipped with 'type' prop which is function
  94. // to define the valid rule, e.g UserNameType need to be non empty, and valid email format
  95. <CustomTextInput
  96. value={this.state.username}
  97. keyboardType='email-address'
  98. onChange={this.handleInputChange.bind(this, 'username')}
  99. type={UserNameType}
  100. />
  101. <CustomTextInput
  102. value={this.state.password}
  103. secureTextEntry={true}
  104. onChange={this.handleInputChange.bind(this, 'password')}
  105. type={PasswordType}
  106. />
  107.  
  108. {this.renderLoginBtn()}
  109.  
  110. <Spinner waiting={SessionStore.pending} />
  111. </ScrollView>
  112. )
  113. }
  114. }
  115. ```
  116.  
  117. **UserActionCreators.js**
  118. ```js
  119. import SharedDispatcher from '../SharedDispatcher';
  120. import {ActionTypes} from '../constants';
  121. // Encapsulate sending api request to proper endpoint
  122. import UserAPI from './UserAPI';
  123.  
  124. // Singleton Flux dispatcher to dispatch actions
  125. // We extend it to be able to dispatch promise (async actions), call the real
  126. // dispatch after promise resolved or rejected, similar idea to redux thunk middleware
  127. const dispatcher = SharedDispatcher();
  128.  
  129. export function requestLoginWithEmail(username, password) {
  130. // this is how we use dispatchAsync
  131. return dispatcher.dispatchAsync(
  132. UserAPI.login(username, password), ActionTypes.USER_LOGIN_EMAIL
  133. )
  134. }
  135.  
  136. // authData is obtained from Facebook login SDK
  137. export function requestSignInWithFB(authData) {
  138. return dispatcher.dispatchAsync(
  139. UserAPI.logInWithFB(authData), ActionTypes.USER_LOGIN_FACEBOOK
  140. )
  141. }
  142. ```
  143.  
  144. **UserAPI.js**
  145. ```js
  146. export function login(username, password) {
  147. // Parse is client wrapper to deal with backend api,
  148. // do encoding request parameters and decoding response object etc
  149. return Parse.User.login(username, password)
  150. .then(user => {
  151. // do other stuff, like update installation table
  152. // resolved with logged in user object
  153. // this will be dispatched along with action payload
  154. return user;
  155. })
  156. }
  157. ```
  158.  
  159. **SessionStore.js**
  160. ```js
  161. // inital state
  162. var _state = {
  163. type: undefined,
  164. requestStatus: undefined,
  165. error: null
  166. }
  167.  
  168. class SessionStore extends Store {
  169.  
  170. get pending() {
  171. return _state.requestStatus === 'pending';
  172. }
  173.  
  174. get ready() {
  175. return _state.requestStatus === 'ready' ? true : false;
  176. }
  177.  
  178. __onDispatch(action) {
  179. const {type, payload} = action;
  180. switch (type) {
  181. case ActionTypes.USER_LOGIN_EMAIL:
  182. // deal with action payload
  183. let newState = {type, requestStatus: payload.status};
  184. if (payload.status === 'ready') {
  185. Object.assign(newState, payload.response);
  186. }
  187. if (payload.error) {
  188. Object.assign(newState, payload.error);
  189. }
  190. // merge with previous state to produce next state shape
  191. _state = {..._state, ...newState};
  192.  
  193. // notify subscribed component
  194. this.__emitChange();
  195. break
  196. case ActionTypes.USER_LOGIN_FACEBOOK:
  197. // similar to normal log in
  198. default:
  199. break;
  200. }
  201. }
  202. }
  203. ```
Add Comment
Please, Sign In to add comment