最近Expoでアプリ書いてるのに使ったTipsなど
React Native Advent Calendar 2018 - 17日目の記事です
最近Expoでアプリを書いているので、そこで使った小ネタを紹介
独自実装したモーダルの動き#reactnative #expo pic.twitter.com/bBKOtMKdvk
— .あーる (@DotEarl) December 3, 2018
画面全体を覆うスタイルを定義したい時
Stylesheet.absoluteFillObject
画面全体をピッタリ覆うスタイルを付けたい時に使えます
export default class App extends React.Component { render() { return ( <View style={styles.container}> <TouchableOpacity> <Text>Button</Text> </TouchableOpacity> <View style={styles.fill} /> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center' }, fill: { // 縦横いっぱいでabsoluteなViewのスタイルを設定 ...StyleSheet.absoluteFillObject, // わかりやすく色を付けてる backgroundColor: 'rgba(255, 0, 0, 0.2)' } });
赤くなってる範囲が <View />
に absoluteFillObject
を設定した範囲です
いつ使うのか? 例えば環境に影響されない(どこに置いても成り立つ)フローティングボタンを作りたい場合などに使えます
被さったViewのタッチ判定を無効化する
当たり前ですが、このままだと赤いマスクの裏の画面が全く触れなくなってしまいます
そんな時は <View />
に pointerEvents="box-none"
を設定します
<View style={styles.fill} pointerEvents="box-none"> // ... </View>
全面にある赤い <View />
のタップ判定を無効にして、なにもないように振る舞わせることができます
意外と色んなところで使えそう
キーボードの上に「完了」とか付けるやつの実装
これ、よく使うと思います
RNにもともと入ってる InputAccessoryView
コンポーネントで実装はできますが、バギーで使えませんでした
自分で実装したんですが、ここでも pointerEvents="box-none"
が出てきます
スペーサーに外部のライブラリ使ってますが
import React from 'react'; import { View, ViewProps, StyleSheet } from 'react-native' import KeyboardSpacer from 'react-native-keyboard-spacer'; interface Props extends ViewProps { children: React.ReactNode; } export const InputAccessoryView = ({ children, ...rest }: Props) => ( <View {...rest} pointerEvents="box-none" style={styles.wrap}> {children} <KeyboardSpacer /> </View> ) const styles = StyleSheet.create({ wrap: { ...StyleSheet.absoluteFillObject, justifyContent: 'flex-end', } })
children
がキーボードの上に乗るところです
あとはこのコンポーネントを使って好きに実装します
import React from 'react'; import { View, ViewProps, TouchableOpacity, Text, Keyboard } from 'react-native' import { InputAccessoryView} from './InputAccessoryView' import styled from 'styled-components' const Inner = styled(View)` align-items: flex-end; padding: 12px 16px; background: #f2f2f2; `; const TextButton = styled(TouchableOpacity)` font-weight: bold; color: #15a2ff; `; interface Props extends ViewProps { visible?: boolean; onClosed?: () => void } export const InputAccessory = ({ visible, onClosed, ...rest }: Props) => { if (visible === false) { return null } return ( <InputAccessoryView {...rest}> <Inner> <TextButton onPress={() => { if (onClosed) { onClosed() } Keyboard.dismiss() }} > <Text>完了<Text> </TextButton> </Inner> </InputAccessoryView> ) } Accessory.defaultProps = { visible: true, onClosed: undefined, }
例えばこんな感じ
「完了」ボタンを置いてキーボードが閉じるように実装します
<InputAccessoryView />
はただキーボードの上に乗る要素を作るだけのコンポーネントです
https://gist.github.com/rskull/3fb91f4c19f49d86355987d1c35fbb35
まとめ
かなりざっとな記事ですみません
3ヶ月くらいExpoで開発してる感想は、めっちゃ楽の一言でした
以前素のRNを2年半くらい触ってましたが、ビルドは落ちるし時間かかるしで辛かったです(当方ネイティブ初心者なので...)
プロジェクトごとにアカウントを作って、そのアカウントをメンバーで共有すれば
コマンドでデプロイ後すぐにシェア、確認できるのですごい作業がはかどりました
なんとかリリースまでこぎつけたいですね
以上です。良いお年を
Typescript + React + Redux + SSR 辺りの素振り
仕事で使うことになりそうなので素振り
要点を抑えながらシンプルめに書いてみた
インクリメントするだけのアプリ
セットアップ
基本的なの
$ yarn add react react-dom redux react-redux $ yarn add --dev typescript ts-loader webpack webpack-cli
型情報も入れる
$ yarn add --dev @types/react @types/react-dom @types/react-redux
サーバー側
$ yarn add fastify serve-static $ yarn add --dev @types/serve-static
ディレクトリ構成
SSRするのでクライアントとサーバー側それぞれでエンドポイントを用意してる
├── app // 共通のコード ├── client │ └── index.tsx ├── server │ ├── Html.tsx │ └── index.tsx ├── tsconfig.client.json ├── tsconfig.json ├── webpack.config.js └── package.json
最終的なコード
yarn start
するとサーバーが立ち上がって、初回のSSRだけされるようになってる
参考にした記事
ReactNative アップグレード対応 v0.52 -> v0.56
みんな大好き恒例のアップグレードをしたので、その時にハマった事のメモ
今回は v0.52.2
から v0.56.0
にアップグレードした
前回のアップグレードよりは楽だったけど、本体のバグらしき罠にだいぶはめられた
ちなみに前回と同じく $ react-native-git-upgrade
は使わずに
$ react-native init myApp
で新たに作成したフォルダに自力で差分をみてマージをしてる
なんだかんだこの方法が一番キレイに出来る
差分の確認
念の為、今回のアップデートの差分を目視確認しておく
自分の環境に合わせて差分が見れるので、それを適用すればOK
Comparing rn-0.52.2...rn-0.56.0 · ncuillery/rn-diff · GitHub
Androidの compileSdkVersion
などが上がった対応
おそらくこれが今回の一番大きな変更
- compileSdkVersion
23
->26
- buildToolsVersion
23.0.1
->26.0.3
- targetSdkVersion
22
->26
これにより、依存してるサードパーティが大体 23
のため、警告が出たりビルドが落ちたりする
正しい対策じゃないかもしれないけど
android/build.gradle
に以下のコードを追加して対応した
subprojects { afterEvaluate {project -> if (project.hasProperty("android")) { android { compileSdkVersion 26 buildToolsVersion '26.0.3' } } } }
警告出されたけどビルドは通るようになった
※ 正しい方法があったら教えて下さい!
リリースビルドのアプリを起動すると直後にクラッシュする
こんなエラーが出てた
undefined is not an object (evaluating 'r.default')
結果的にいうと、原因は react-navigaiton
だった
PRは却下されてるけど、とりあえずこの修正を適用すると動くようになる
import
が正しく出来ないバグっぽいので、根本的な理由は多分 babel7
に移行したことで何か問題が起きてるのかな??
flowのエラー
型が強化されたみたいで、エラーがたくさん出た
気合で直す
CocoaPodsの修正
BatchedBridge
がなくなって、代わりに CxxBridge
を追加した
pod 'React', :subspecs => [ // ... + 'CxxBridge', - 'BatchedBridge' ], :path => '../node_modules/react-native'
正直このへんよくわからないし触りたくない
Jestが実行できない
Jestを実行すると、そもそも動かなくていろんなエラーがでて落ちる
Issueはこれ
package.json
に以下のコードを追加したら動くようになった
"jest": { "preset": "react-native", "transform": { "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js" } }
これはとりあえずの回避策で
PRはちゃんと出てるみたい: Fix jest-preset to use internal preprocessor (fix testing with 0.56) by vovkasm · Pull Request #20068 · facebook/react-native · GitHub
動くようになった
自分がハマったのはこれくらいです
--
※ 2018/07/25 追記
TextInputの日本語入力が出来ない件
すっかり忘れてたけど、直ってないじゃん!!
今の所、これが最善っぽい?
TwitterKitを使ってるアプリでWeb経由の認証が出来なくなったのを解決した
Twitterの仕様変更
本日(2018/06/12)に認証周りの仕様が変わった。
認証して戻ってくる時のコールバックURLをデベロッパーの管理画面で設定するのが必須になった
Callback URL — Twitter Developers
TwitterKitを使ってログインを実装してるアプリで、端末にTwitterが入ってなければブラウザが立ち上がって認証が行われる
その場合、コールバックURLの設定をしてないと認証がコケるようになってしまった
ちなみにReactNativeアプリの開発でTwtiterの認証にreact-native-twitter-signin
を使っている
修正
アプリの管理画面の設定を開く
コールバックURLに
twitterkit-YourConsumerKey://
の形式で登録する
これはTwitterKitがコールバックURLとして使っているもの
YourConsumerKeyは自分のアプリのコンシューマーキー
://
を末尾に付けないと登録出来ないので注意
..
登録が終わったら、コールバックをロックしても正常に認証出来るようになった
※ 追記(2018/06/14)
上記の対応だと、AndroidのWeb経由だけ認証が通らなかった
合わせて下記の対応でiOS(Twitter経由/Web経由)Android(Twitter経由/Web経由)すべての経路で認証が通るようになった
TwitterKit使用しててログインできなくなったアプリは、callbackのurlにtwittersdk://を追加すればiOS/Androidともにログインできるようになった。
— Mikiya Fukuda (@musclemikiya) June 14, 2018
ちなみにtwittersdk://
の対応だけだとiOSのWeb経由が通らなくなった(僕の環境だと)
この辺の挙動アナウンスないしほんと謎