React Native 开发系列4 单词卡片

react-native | Comments

隔了好久,总算把真正涉及到学习的第一部分–学习卡片完成了。这段时间用了很多新东西,也学到了很多东西, 开始对react native有点感觉了,现在可以很快的把一块UI放到一个component里面。 以前写js用的还是jQuery和Backbone,现在ES6的各种增强语法用起来已经完全能够胜任UI的开发。这些天做的东西比较多,所以这篇提到的东西也会比较多。

ps: 以前的目录就不更新了,反正可以点过来

目录

  1. 项目搭建 – 底部导航栏及搜索
  2. 实现搜索 – 调用API及自定义组件
  3. 登录注册 – 使用cookies
  4. 学习卡片 – flash/swipe card

写了一个简单的fetch wrapper

react native中推荐使用fetch来调用网络请求,项目中慢慢开始有越来越多的地方要调用API获取数据,以前fetch的写法太原始,每个地方都要传递header,处理错误,所以仿照以前jquery中ajax的写法,写了一个工具函数fetcher,之后就可以很方便的调用API。

1
2
3
fetcher.get(taskUrl, (data) => {
  this.setState({ task: data, });
});

配置eslint和beautify

之前没怎么注意代码风格,随着代码变多,如果不遵守代码规范,代码也会变得越来越乱。我用的Atom做react native的开发,Atom里有很多好用、现成的插件来提升开发效率,用了eslintatom-beautify两个插件,前一个可以自动提示错误的代码写法,后一个可以在保存时自动格式化代码。虽然改了挺多地方,不过也学到了很多ES6中的best practice。

atom的eslint插件还需要配合一些其他工具才能使用。

安装eslint需要的包

1
npm install --save-dev eslint-config-airbnb babel-eslint eslint-plugin-react

在项目中创建一个.eslintrc的文件,

1
2
3
4
5
6
7
8
9
10
# .eslint
{
  "env": {"browser": true}, # fix 'fetch' undefined
  "extends": "airbnb",      # coding style
  "parser": "babel-eslint", # default eslint parser does not support some feature
  "plugins": [
    "react"
  ],
  "rules":[...]
}

实现卡片效果 – 1. 点击反转

用了react-native-flip-card, 做的时候碰到了一个问题, 把FlipCard嵌套到其他View里面的时候,高度总是不对,最后还是没能找到原因,通过设置flex:0disable了默认的flex效果,才暂时解决,不过应该有更好的解决办法才对。

这个插件没有什么依赖,按照他的文档安装后就能使用,不过他只提供了一个onFlipped属性,在卡片反转完成后执行想要的动作,因为我需要在卡片反转时就播放一个提示音频,所以自己fork了一份,添加了onFlipStartonFlipEnd。给作者提了PR,不知道会不会合进去。

实现卡片效果 – 2. 滑动切换

用了react-native-tinder-swipe-cards,这个component和上面的flip card有点冲突,准确的说是和所有Touchable*都有冲突,因为PanResponse默认会拦截所有触控事件,这样被滑动的卡片就没法有自己的点击效果。详细的解释可以参考这里 – react-native-maintain-touchable-items-with-a-parent-panresponder.

另外一个问题是这个实现的默认效果,左滑和右滑都是到下一个card,我需要能够回到上一个card,自己fork了一份,修改了左滑的逻辑,并且修改了onStartShouldSetPanResponderCapture方法,让被滑动的卡片响应点击事件。具体修改在这里

播放音频

使用react-native-sound, 按照文档安装后就能使用,不过文档很多地方说的不全,说一下我碰到的两个问题。

播放音频地址时,第二个参数需要传一个空字符串, 而不是不传

1
2
3
4
5
6
7
8
const sound = new Sound(audioUrl, "", (error) => {
  if (error) {
    console.log("Failed to load the sound", audioUrl, error);
  } else {
    console.log("play sound file: ", audioUrl);
    sound.play();
  }
})

javascript

播放本地mp3文件时,需要先用xcode把文件添加到项目中,然后重启模拟器才能生效

1
2
3
4
5
new Sound(`chord.mp3`, Sound.MAIN_BUNDLE, (error) => {
  if (error) {
    console.log("failed to load the sound", error);
  }
});

大概就是这些东西,还有些零碎的部分和中间有段时间想本来想把redux加进来,看了一些redux的资料,的确是很好的的设计,不过目前项目还很小,现在用redux觉得还是有点早了,最后还是决定第一个版本都不再考虑redux,后面如果有机会重构,再把redux加进来。

看看现在的效果:

完整的代码见GitHub day4

Comments