美团客户端
视频教程
现已推出全套视频教程,从创建工程讲起,一行一行编写代码,直至完成整个项目。
腾讯课堂
网易课堂
Github:https://github.com/huanxsd/MeiTuan
简书:http://www.jianshu.com/p/9211f42d5c25
iOS截图
![](https://img.haomeiwen.com/i5685774/258f786552482594.png)
![](https://img.haomeiwen.com/i5685774/988195b64c56f9b6.png)
![](https://img.haomeiwen.com/i5685774/e06e33c212dc873f.png)
Android截图
![](https://img.haomeiwen.com/i5685774/497a8c929fe79528.png)
![](https://img.haomeiwen.com/i5685774/339c9b0de65c2c12.png)
![](https://img.haomeiwen.com/i5685774/7d2d1ce1cd54d2b0.png)
简介
这是一个用React-Native写的美团客户端。
主要实现了美团的四个一级页面(团购、附近、订单、我的),以及部分二级页面(团购详情、Web页面)。
所有功能都是用JavaScript写的,iOS和Android的代码复用率达到了97%(别问我这个数字怎么来的,我瞎掰的)。
这个Demo的静态类型检查工具使用了Facebook的Flow。它让我写JavaScript的时候,更有安全感。个人觉得可以用两个字形容这个工具,那就是:灰常牛逼!
我试着让这个Demo的结构尽量接近实际项目,同时使用比较简单方式去实现功能。这样可以让刚接触ReactNative的人(比如我自己...)更够容易理解代码。
所有的JS代码都在src目录下。
目录结构
![](https://img.haomeiwen.com/i5685774/5f508278a8fe00dc.png)
- common
通用的工具类 - img
所有图片资源 - scene
所有场景 - widget
通用的UI控件 - api.js
网络请求的接口 - RootScene.js
App的主入口,类似iOS中的RootViewController
该项目没有使用Redux。因为个人觉得目前大部分的中小型App并不需要Redux。如果盲目的将Redux添加到项目中,并不能带来太多的益处。
鲁迅曾说过:
"如果你不知道是否需要 Redux,那就是不需要它。"
Redux的作者 Dan Abramov 说过:
"只有遇到 React 实在解决不了的问题,你才需要 Redux 。"
哦,另外一个没有用Redux的原因,是我还不太会用。
App的页面跳转、TabBar、Navigation,全部通过react-navigation实现。这是一个非常牛逼的库,可以实现很多自定义的跳转功能。最早是通过react-native-router-flux实现跳转。在遇见react-navigation后,我果断放弃了react-native-router-flux。
App中很多页面都使用了同一个网络接口,这不是为了让代码更加简洁,仅仅是我偷懒 >.<
第三方依赖
安装
- Clone the repo
$ git clone https://github.com/huanxsd/MeiTuan.git
$ cd MeiTuan
- Install dependencies (npm v3+)
$ npm install
- Running on iOS
$ react-native run-ios
常见问题
Could not connect to development server
打开新的terminal窗口,并执行:
$ react-native start
瞎扯蛋
我之前一直在写Objective-C,但不久前看了ES6的语法和Flex布局方式后,我便马上爱上了这种开发方式。
这个Demo花了大概5天时间,是我的第一个ReactNative项目。
如果对这个Demo有任何的意见或建议,或者喜欢ReactNative的朋友,欢迎在下方留言。我会在第一时间回复 :)
最后
如果你喜欢这个Demo,请给我一个star :)
Github:https://github.com/huanxsd/MeiTuan
我将持续更新这个Demo
更多阅读
LinkMap解析工具:检查每个类占用大小
最灵活的UI控件库:React Native UI Lib
React Native开发实用技巧
基于FlatList的上拉、下拉刷新组件
ReactNative交流群
![](https://img.haomeiwen.com/i5685774/957c90b45c8f8912.png)
网友评论
这怎么解决啊
undefined is not a function(evaluating 'arr[typeof Symbol ==="fnction" ? Symbol.iterator:"@@iterator"]()'
2525 silly fetchPackageMetaData error for js-yaml@^3.7.0 Unexpected end of input at 1:24865
2525 silly fetchPackageMetaData a":"^2.6.0"},"devDependencies":{"ansi":"*","benchmark":"*","browserif
2525 silly fetchPackageMetaData ^
2526 verbose stack SyntaxError: Unexpected end of input at 1:24865
2526 verbose stack a":"^2.6.0"},"devDependencies":{"ansi":"*","benchmark":"*","browserif
2526 verbose stack ^
2526 verbose stack at Object.parseJSON (/usr/local/lib/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/node-fetch-npm/node_modules/json-parse-helpfulerror/node_modules/jju/lib/parse.js:745:13)
2526 verbose stack at parse (/usr/local/lib/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/node-fetch-npm/node_modules/json-parse-helpfulerror/index.js:10:13)
2526 verbose stack at consumeBody.call.then.buffer (/usr/local/lib/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/node-fetch-npm/src/body.js:96:50)
2526 verbose stack at <anonymous>
2526 verbose stack at process._tickCallback (internal/process/next_tick.js:188:7)
2527 verbose cwd /Users/zhangdongdong/MeiTuan
2528 verbose Darwin 16.7.0
2529 verbose argv "/usr/local/Cellar/node/8.2.1/bin/node" "/usr/local/bin/npm" "install"
2530 verbose node v8.2.1
2531 verbose npm v5.3.0
2532 error Unexpected end of input at 1:24865
2532 error a":"^2.6.0"},"devDependencies":{"ansi":"*","benchmark":"*","browserif
2532 error ^
2533 verbose exit [ 1, true ]
npm ERR! a":"^2.6.0"},"devDependencies":{"ansi":"*","benchmark":"*","browserif
npm ERR!
1、RefreshListView的startHeaderRefreshing()中 this.props.onHeaderRefresh && this.props.onHeaderRefresh() 前面容易理解调用的是父组件传过来的方法,后面的是调用的是自己的方法,为什么不用this而是用this.props?
2、NearbyListScene 中
listView: ListView
.....
componentDidMount() {
this.listView.startHeaderRefreshing();
}
this.listView不是ListView组件类型么,该类型没有这个方法,怎么能调用RefreshListView的startHeaderRefreshing()方法?
返回404 怎么回事?
static navigationOptions = ({ navigation }) => ({
header:null
})
部分图片的高度和宽度的逻辑点是写死的,在不同设备上渲染的时候,会自动换算成像素点。
[js]types can only be used in a ts file
"javascript.validate.enable": false
我赞成复杂的项目用redux,肯定会方便很多
对于简单的项目,个人觉得代码简洁易读是排在第一位。
redux强制分了view,action,reducer。对于简单的逻辑,个人觉得没有必须.
正如mvc可以轻松应对的事情,没有必要用mvvm一样
可以参考下这个类的实现,不知是否可以解决你的需求
https://github.com/huanxsd/MeiTuan/blob/master/src/widget/RefreshListView.js
react-native bundle --entry-file index.ios.js --bundle-output ./ios/index.ios.jsbundle --platform ios --assets-dest ./ios --dev false
http://reactnative.cn/docs/0.43/running-on-device-ios.html#content
http://reactnative.cn/docs/0.43/running-on-device-android.html#content