ericwooley / react-nativeish

React Native / React Native Web Boilerplate
MIT License
106 stars 7 forks source link

Create upgradeable package. #15

Closed ericwooley closed 6 years ago

ericwooley commented 7 years ago
DaKaZ commented 6 years ago

@ericwooley I recently stumbled across this repo thanks to your linkage in react-native-web. I am very excited because we have been building a web/ios/android "boilerplate" for our work since June and our design patterns are almost identical. We too use sagas, redux, and react-navigation. I was very interested in your comment about react-native@0.42 having serious networking issues. We are running on 0.42.3 ourselves and while I have not experienced these issues, I am hesitant to downgrade to 0.41. Can you tell me what you meant when you called that out on your readme?

Additionally, the only design pattern we have that you did not follow is the Ducks pattern for redux. I absolutely love this and think it makes working with redux significantly easier. Every duck file exports the actions, types, and reducer. Here is an example from our project, you can image how easy it is to import from any duck file with `import { actions as authActions } from '../ducks/auth';:

// src/ducks/auth.js
// @flow

import type { NavigationProp } from 'react-navigation';

export type UserType = {
  name: string,
  email: string
};

export type LoginRequestType = {
  type: 'AUTH/LOGIN_REQUEST',
  email: string,
  password: string
};

export type LoginSuccessType = {
  type: 'AUTH/LOGIN_SUCCESS',
  user: UserType,
  token: string
};

export type LoginFailureType = {
  type: 'AUTH/LOGIN_FAILURE',
  message: string
};

export type LogoutType = {
  type: 'AUTH/LOGOUT'
};

/*****
FIXME: we should be using explicit types for our actions, but its not working

export type ActionType =
  ( LoginSuccessType
  | LoginRequestType
  | LoginFailureType
  | LogoutType );

*******/

export type ActionType = {
  type: string,
  user?: UserType,
  email?: string,
  password?: string,
  message?: string,
  token?: string
};

export const types = {
  LOGIN_REQUEST:       'AUTH/LOGIN_REQUEST',
  LOGIN_SUCCESS:       'AUTH/LOGIN_SUCCESS',
  LOGIN_FAILURE:       'AUTH/LOGIN_FAILURE',
  LOGOUT:              'AUTH/LOGOUT',
  UPDATE_CURRENT_USER: 'AUTH/UPDATE_CURRENT_USER',
};

// action creators
export type ActionCreatorsType = {
  loginRequest: (email: string, password: string)=> LoginRequestType,
  loginSuccess: (user: UserType, token: string)=> LoginSuccessType,
  loginFailure: (message: string)=> LoginFailureType,
  logout: ()=> LogoutType,
};

export const actions = {
  loginRequest: (email: string, password: string): LoginRequestType => ({ type: types.LOGIN_REQUEST, email, password }),
  loginSuccess: (user: UserType, token: string): LoginSuccessType => ({ type: types.LOGIN_SUCCESS, user, token }),
  loginFailure: (message: string): LoginFailureType => ({ type: types.LOGIN_FAILURE, message }),
  logout: (): LogoutType => ({ type: types.LOGOUT }),
};

export type StateType = {
  user: ?UserType,
  isLoading: boolean,
  error: ?string,
  apiToken: ?string,
};

// default authReducer state
export const initialState = {
  user: null,
  isLoading: false,
  error: null,
  apiToken: null,
};

const defaultAction = { type: '' };

// auth reducer
export function reducer(state: StateType = initialState, action: ActionType = defaultAction): StateType {
  switch (action.type) {
    case types.LOGIN_REQUEST:
      return { ...state, isLoading: true };

    case types.LOGIN_SUCCESS:
      return { ...state, isLoading: false, user: action.user, error: null, apiToken: action.token };

    case types.LOGIN_FAILURE:
      return { ...state, isLoading: false, error: action.message, user: null };

    case types.LOGOUT:
      return { ...state, isLoading: false, user: null, error: null, apiToken: null };

    default:
      return state;
  }
}
ericwooley commented 6 years ago

I'm glad you like the boilerplate!

41 issue

IIRC it was an issue where certain requests wouldn't go through under certain circumstances on that last version of 42. I found a react native issue that said it was fixed in 43, but they also added the dependency on react.16.alpha in that release. So i couldn't upgrade to that. I can't find the issue now, but I remember that it was something to do with android network requests silently failing. I wish I had copied down the issue when I found it.

Duck typing

If you look at https://github.com/ericwooley/react-nativeish/blob/master/src/redux/reducers/counter/counterReducer.js

It is essentially the duck pattern, counter exports the reducer, action types, and action creators. In any case, the boilerplate code is actually checked into the repository here. So you can edit that to match the pattern you like.

Alternative branch.

Also there is another, less polished (I think the docs are outdated, and boilerplate is gone), branch you may be interested in, https://github.com/ericwooley/react-nativeish/tree/upgrade-rn But I did a ton of work with react router v4 and react-navigation. Last time i checked, the latest version of react-navigation did not work in the browser any longer. Hopefully you can get some use out of it, or when you encounter errors with the current setup, you can reference that.

Which allows you to use the later versions of react native (by installing the correct dependencies just before run, which is gross, but the only decent way to do it at the moment).