最近在公司做了一个webapp 用了react和redux
然后公司想用react-native 重构之前的app,而且要和webapp代码复用(主要是redux代码),界面还是web一套,native一套
项目结构问题
子模块
现在使用的是 git 的子模块功能,就相当于2个项目公用一个公共的目录 目录结构如下(common目录为子模块)
# web 项目
root
--client //web 项目代码
----libs //自己写的模块
------storage.js //web数据模块
--common //子模块
----imgs // 图片目录
----redux // redux 目录
------actions
------data
------reducers
# react-native 项目
root
--client //web 项目代码
----libs //自己写的模块
------storage.js //native数据模块
--common //子模块
----imgs // 图片目录
----redux // redux 目录
------actions
------data
------reducers
babel 配置
web端
# .babelrc
{
"presets": ["react", "es2015", "stage-3"]
}
还要在入口文件处引入babel-polyfill
# index.js
import 'babel-polyfill'
native端
# .babelrc
{
//这个可以兼容 async function
"presets": ["react-native-stage-0"]
}
redux 问题
使用的redux库
import promiseMiddleware from 'redux-promise';
import axiosMiddleware from 'redux-axios-middleware';
const enhancers = compose(
applyMiddleware(
promiseMiddleware, //异步action 中间件
axiosMiddleware(axios), //axios 中间件
)
);
action
export function messageList() {
let local = localStorage.getItem('timestamp') || '0'
return {
type: 'MESSAGE_LIST',
payload: {
request: {
method: 'get',
url: '[url]' + '?timestamp=' + local
},
}
}
}
之前在写web端的时候 有过在aciton里获取localstorage中的数据,到了react-native中就碰到问题了,因为react-native中没有找到同步获取本地数据的方法,所以之前的代码就不能复用了,引入redux-promise这个库解决异步action的问题,它可以让action的返回值是promise就把本地存储封装一下让2端都可以用一套代码。代码如下(web也需封装一下,但不用async)
import storage from '../../../client/libs/storage.js' //
export async function messageList() {
let local = await storage.getItem('timestamp')
return {
type: 'MESSAGE_LIST',
payload: {
request: {
method: 'get',
url: '[url]' + '?timestamp=' + local
},
}
}
}
# storage.js native
import { AsyncStorage } from 'react-native'
export default {
getItem : async function (key){
let value = await AsyncStorageGetItem(key)
return value
}
}
async function AsyncStorageGetItem(key) {
return new Promise((resolve,reject)=>{
AsyncStorage.getItem(key, function (value) {
resolve(value)
})
})
}
# storage.js native end
# storage.js web
export default {
getItem : function (key){
return JSON.parse(localStorage.getItem(key))
}
}
# storage.js web end
reducers
目前没有找到在 reducers 中使用异步操作的方案,所以只能取巧的把reducers中需要用到的本地数据在actions时传入,像下面这样 aciton.meta.previousAction 这个是 redux-axios-middleware 库的 ,具体的可以看我这篇文章
export async function messageList() {
let local = await storage.getItem('timestamp')
let reducersData = await storage.getItem('[key]')
return {
type: 'MESSAGE_LIST',
payload: {
request: {
method: 'get',
url: '[url]' + '?timestamp=' + local
},
},
reducersData: reducersData
}
}
case 'MESSAGE_LIST':
return state;
case 'MESSAGE_LIST_SUCCESS':
// 从上一个action中获取数据
let previousActionData = aciton.meta.previousAction.reducersData
return state;
case 'MESSAGE_LIST_FAIL':
return state;
data
data 中一般定义一些默认值,但是如果要从本地拿数据再赋值 目前找不到什么好方法,待解决吧
{
//web中可以这样写 native中就很难实现了
timestamp: localStorage.getItem('approvalListData.timestamp') || { }
}
目前就碰到这些问题,之后有问题再更新~