用react-native开发原生应用

Q: 前端领域,还有什么框架可以开发原生应用?(至少三种)

react-native

基于react构建手机应用的框架

封装了常用的手机端原生接口、组件

搭建开发环境

http://facebook.github.io/react-native/docs

目录

什么是react-native

文件结构

实例演示

开发应用的技术栈

redux数据流

react的组件化思维

文件结构

实例演示

开发应用的技术栈

react

state: this.state.btn

this.setState({btn: true})

props: this.props.color

当页面变得复杂

页面逻辑复杂

多状态传递

数据需要共享

后期维护一个文件?

redux

                    
                    
                    store = createStore(reducer)
                    
                    
                    

                    
                    store.dispatch(loginReduxAc({
                        username: this.username._lastNativeText
                        password: this.password._lastNativeText
                    }))
                    
                    export const loginReduxAc = data => action(USER, { ...data });
                    
                    export const action = (type, payload = {}) => {
                        return { type, ...payload };
                    };
                    
                    const user = (state = {islogin: false, info: {}}, action) => {
                        if (action.type === USER){
                            return {
                                isLogin: true,
                                info: {
                                    username: action.username,
                                }
                            }                  
                        }
                        return state;
                    }
                    export default combineReducers({
                        user,
                        newsList: newsListFn,
                        ...
                    });

                    
                    store = {
                        user: {login: false, .....}
                    }
                    
                    

Q: pure function是什么?

middleware

接收请求到产生响应的过程, 本质是hack

本质

                        
                        function m1(store){
                            const next = store.dispatch;
                            store.dispatch = function(action) {
                                console.log('m1 begin');
                                next(action);
                                console.log('m1 end');
                            }
                        }
                        function m2(store){
                            const next = store.dispatch;
                            store.dispatch = function(action) {
                                console.log('m2 begin');
                                next(action);
                                console.log('m2 end');
                            }
                        }
                        m2(store);
                        m1(store);
                        store.dispatch({type: 'EE'});

                        结果:
                        m1 begin > m2 begin > m2 end > m1 end
                        
                    

传统子例程的堆栈方式:先进后出

Q: 在中间件中调用next和store.dispatch的区别?

柯里化

                        
                        store => next => action => {
                            if(typeof action == 'function'){
                                action(store, next)
                            }else {
                                next(action)
                            }
                        }
                        
                    

补充一个API

applyMiddleware: 接收链式middleware

applyMiddleware(thunk, logger)

const store = createStore(reducers,{},enhancer);

本质

applyMiddleware = (...middleware) => (createStore) => (reducer, preloadedState, enhancer) {}

所以

applyMiddleware(thunk, logger)(createStore)(reducers)

异步action

request.js

Q:request.js中用到了哪些es6的语法?(至少三种)

优化

service API集中处理

每个fetch请求的method、header可能不同

多个请求并行

多个请求串行

sagas

长事物模型,管理side-effects的途径

1. 对acion dispach事件做出反应

2. dispach新的actions

3. 在没有action被dispath的情况下能够运用内部机制进行自我苏醒

redux-saga

saga是generator 函数

协程多个线程并行执行,只有一个线程处于执行状态,其它线程处于暂停态


    function* loadLogin() {
        const params = yield select(getLoginInfo);
        yield call(fetchEntity, loginSagasAc, api.fetchLogin, params, function* (response) {
            yield put(user({ isLogin: true, info: response.data.info}));
            yield put(loginSagasAc.success());
        });
    }

    var loadLoginHandler = loadLogin();
    loadLoginHandler.next();  // {value: xxx, done: false}

                    

做所有与state相关的异步操作, 保持视图和action creator 是纯函数

react-redux

HOC

Provide

Connect

                    
      
        
      
      // LoginSagas.js
      connect(
        (state) => {
            const { account } = this,state;
            return {
            userData: account.user,
            loginData: account.login,
            };
        },
        (dispatch) => {
            return {
            loginReq: (obj) => {
                dispatch(loginSagasAc.request(obj));
            },
            };
        })(LoginSagas);
                    
                        

react-persist

react-native: AsyncStorage

                        
const enhancer = compose(
  autoRehydrate(),
);
const store = createStore(
  reducers,
  {},
  enhancer,
);
export default configureStore(onComplete) {
  persistStore(store, { storage: AsyncStorage }, onComplete);

  if (isDebuggingInChrome) {
    window.store = store;
  }
  return store;
}
                        
                    

redux数据流



const sagaMiddleware = createSagaMiddleware({ sagaMonitor });

const enhancer = compose(
  autoRehydrate(),
  applyMiddleware(sagaMiddleware, thunk, logger),
);
const store = createStore(
  reducers,
  {},
  enhancer,
);
sagaMiddleware.run(rootSaga);

function configureStore(onComplete) {
  // TODO: 建议开始把redux-persist关闭,因为它会对state进行缓存,可能对于一些state对象调试不是很方便
  persistStore(store, { storage: AsyncStorage }, onComplete);

  if (isDebuggingInChrome) {
    window.store = store;
  }
  return store;
}


    


export default connect(
  (state) => {
    return {
      userData: state.account.user,
    };
  },
  (dispatch) => {
    return {
      loginReq: (obj) => {
        dispatch(loginSagasAc.request(obj));
      },
    };
  })(LoginSagas);

loginHandler = () => {
this.props.loginReq({
    username: this.username._lastNativeText,
    password: this.password._lastNativeText
});
}

componentWillReceiveProps (nextProps) {
    const { loginData } = nextProps;
    if (this.props.loginData.isFetching && loginData.isFetching){
      if (loginData.status === 0){
        nextProps.userData.isLogin && this.props.navigator.push({
          name: 'TabsView',
          component: TabsView,
          params: {
            iTab: 1,
          }
        });
      } else if (loginData.status === -1){
        this.setState({
          error: '网络错误',
        });
      } else {
        this.setState({
          error: loginData.message,
        });
      }

    }
  }

  export const loginSagasAc = {
	request: data => action(LOGINSAGAS.REQUEST, { ...data }),
	success: () => action(LOGINSAGAS.SUCCESS),
	failure: error => action(LOGINSAGAS.FAILURE, { error }),
};

const REQUEST = 'REQUEST';
const SUCCESS = 'SUCCESS';
const FAILURE = 'FAILURE';

function createRequestTypes(base) {
	return [REQUEST, SUCCESS, FAILURE].reduce((acc, type) => {
		acc[type] = `${base}_${type}`;
		return acc;
	}, {});
}
export const LOGINSAGAS = createRequestTypes('LOGINSAGAS');


export const action = (type, payload = {}) => {
	return { type, ...payload };
};

export default combineReducers({
	...
	login: commonRequest(LOGINSAGAS),
});

function* loadLogin() {
	const params = yield select(getLoginInfo);
	yield call(fetchEntity, loginSagasAc, api.fetchLogin, params, function* (response) {
		yield put(user({ isLogin: true, info: response.data.info}));
		yield put(loginSagasAc.success());
	});
}

export default function* watchAccount() {
	yield takeLatest(LOGINSAGAS.REQUEST, loadLogin);
}
  
                  

react的组件化思维之一: HOC

组件化思维

pure render component

HOC component

render logic

Context

Utility Methods

表单验证需求

1. 实时验证

2. 自定义错误的显示

3. 自定义配置表单验证

react-native-gifted-form、react-native-clean-form...

mixins

es5

redux-form

reduxForm

field

理想实现

redux-form API测试

获取表单数据

hoc

1、链接原生库

2、嵌入原生应用

3、打包

4、编译源码

react-native的利弊

1. 布局的兼容性,特别是android端机型不同、分辨率不同

2. 对原生的API支持还有限

3. 动画是略卡顿的,有些机型表现不一样,需要深入的优化。

4. 还是需要掌握一些原生的东西

1. 有JS的功底就可以写APP,而且可以兼容IOS、Android,很是酷炫。

2. 具有React的优势,数据驱动,高度组件化,很好的管理应用数据,性能好。

3. 生态圈够大,维护者很多