- 投稿日:2020-11-13T23:26:41+09:00
expoで作成したreact nativeアプリをios向けにテスト配布する方法
はじめに
expoで作成したiOSアプリを開発者以外に配布したいという場面で苦戦したのでまとめました。
主に方法は2つ (他にもあればご教授お願い致します)
・ expoでpublishする(無料)
・ Testflight/DeployGateを利用する(Apple Developer Programへ入る必要あり)expoでpublishする(無料)
expo publish
コマンドを実行するとアカウントのProjectページにビルドされたアプリが表示されます。ここで詰まったのが、Projectページに表示されているQRコードをスキャンしたが読み込みに失敗した。
QRコードの真下に書いてあるのだが、この機能が使えるのはandroid端末のみ。
iOSはpublish先のexpoアカウントにログインしていないと使えないらしい。
チームの共有のアカウントを作って、そこにpublishするのが良いかと思います。TestFlightやDeployGateを利用する
.ipaファイルをアップロードする事でテスト配布する事ができます。
expo build:ios
を実行すれば.ipaファイルが作成できますが、Apple Developer Program(年会費$99が必要)に入会していなければ実行できません。
まとめ
自分は今回ハッカソン用に配布したかっただけで、Developer Programに入る程ではなかった為アプリの配布に少し苦戦しました。
同じexpoアカウントに複数人でログインするというのに少し抵抗がありましたが、調べてみた結果これ以外方法が無いかなと思いました。(ハッカソンという時間の問題もあり)ストアへの公開まで考えている方はApple Developer Programに入るのが確実かなと思います。
- 投稿日:2020-11-13T18:39:41+09:00
Styled Componentを使ってアコーディオンを実装する方法【react.js, typescript, javascript, styled-compoent】
TODO
Styled-Componentを使ってアコーディオンアニメーションをさくっと実装
https://styled-components.com/CODE
index.tsconst Accordion = styled.div` max-height: 0; overflow: hidden; max-height: ${props => (props.isHidden ? '0' : '500px')}; transition: max-height 1s; `index.tsfunction ComponentName({isHidden, children}: Props) { return ( <> <div style={{ overflow: 'hidden' }}> <Accordion isHidden={isHidden}> {children} </Accordion> </div> </> ) }
- 投稿日:2020-11-13T18:39:41+09:00
Styled Componentを使ってアコーディオンを実装【react.js, typescript, javascript, styled-compoent】
TODO
Styled-Componentを使ってアコーディオンアニメーションをさくっと実装
CODE
index.tsconst Accordion = styled.div` overflow: hidden; max-height: ${props => (props.isHidden ? '0' : '500px')}; transition: max-height 1s; `index.tsfunction ComponentName({isHidden, children}: Props) { return ( <> <Accordion isHidden={isHidden}> {children} </Accordion> </> ) }REFERENCE
- 投稿日:2020-11-13T08:13:44+09:00
Reactを学ぶVIII 〜ライフサイクルUpdateとUnmountを使う〜
■ はじめに
タイトルについて記事にしました。
この記事で得る内容は以下の通りです。・ Reactの基礎知識が増える
・ ライフサイクル(Update及びUnmount)の実演■ 例(前回の続き)
前回、いいねボタンを作って、ボタンをクリックするとカウントアップした所までやりましたので
次にライフサイクル(Update及びUnmout)を実際に使ってみたいと思います■ componentDidUpdate使用例
内容は、いいね数が10以上になると0に戻るという処理にします
Blog.jsxcomponentDidUpdate() { if (this.count.state >= 10) { this.setState({count:0}); } }いいね数が10以上になると0に戻りました
■ componentWillUnmount記述例
ページを変えるとイベントリスナーが不要になるので
add
だった所をremove
に変えますBlog.jsxcomponentWillUnmount() { document.getElementById("counter").removeEventListener("click",this.countUp); }リスナーの解除を行う事で、リソースが開放され、サーバーに負荷が掛からなくなります
- 投稿日:2020-11-13T07:51:33+09:00
[React]コンポーネントを作るときに他からコピーしてくる作業を自動化するCLIツールを作る
TL;DR
Reactでコンポーネントを新しく作るとき、Storybookやテストも作成するのであれば、ディレクトリを作成してから、
index.ts
,Component.tsx
Component.stories.tsx
Component.spec.tsx
と4ファイルくらい作成することになると思いますが、
毎回これらを手動で作成して、他のコンポーネントからimport文とかをコピーしてくるのは面倒なので、CLIツールを作成して、コマンド一発で出来るようにします。コードはこちら
作ったもの
ディレクトリ構成
AtomicDesign想定です。
. ├── package.json ├── src │ └── components │ └── atoms │ └── Button │ ├── Button.spec.tsx │ ├── Button.stories.tsx │ ├── Button.tsx │ └── index.ts └── tools ├── componentTemplates │ ├── Component.tsx │ ├── Spec.tsx │ ├── Story.tsx │ └── index.ts └── createComponent.jsコード
テンプレート作成
まず、環境に合わせて
./tools/componentTemplates/
以下に、作成したいファイルのテンプレートを配置します。
このテンプレートをリネームして、必要な場所にコピーする感じです。テンプレートはこちらを参照してください。
script作成
コマンドライン引数 オプション
-C
で、コンポーネントの粒度とコンポーネント名を受け取ります。以下はコマンドのhelpです。
Usage: create-component [options] Options: -C, --component [dir/Component] The name of the component to be created (ex) atoms/Button -h, --help display help for command
- 引数が不正である場合はエラー(atoms, molecules, organismsしか許容しない)
- すでにコンポーネントが存在しているときはエラー(上書きしない)
- ディレクトリが存在しないとき(
/molecules/
など未作成の場合)は新規作成します。
コードは以下です。
const { program } = require("commander"); const fs = require("fs"); program.option( "-C, --component [component name]", "The name of the component to be created (ex) atoms/Button" ); program.parse(process.argv); if (!program.component) { program.help(); } const argument = program.component.split("/"); const dir = argument[0]; const component = argument[1]; if (!["atoms", "molecules", "organisms"].includes(dir)) { console.error( "ERROR: Only 'atoms', 'molecules', and 'organisms' can be specified." ); return; } // If the directory is not yet created, create it. if (!fs.existsSync(`./src/components/${dir}`)) { fs.mkdirSync(`./src/components/${dir}`); } const templates = [ "./tools/componentTemplates/index.ts", "./tools/componentTemplates/Component.tsx", "./tools/componentTemplates/Story.tsx", "./tools/componentTemplates/Spec.tsx", ]; const dests = [ `./src/components/${dir}/${component}/index.ts`, `./src/components/${dir}/${component}/${component}.tsx`, `./src/components/${dir}/${component}/${component}.stories.tsx`, `./src/components/${dir}/${component}/${component}.spec.tsx`, ]; fs.mkdirSync(`./src/components/${dir}/${component}`); // Error when a component already exists templates.forEach((template, index) => { fs.copyFileSync( template, dests[index], fs.constants.COPYFILE_EXCL, (error) => { if (error) { throw error; } } ); console.log(`✨ Create component template ${dests[index]}`); });package.jsonに追記
package.json
のscriptsに、"create-component": "node ./tools/createComponent.js"を追記して完了です。
使用例
$ yarn create-component -C atoms/Icon ✨ Create component ./src/components/atoms/Icon/index.ts ✨ Create component ./src/components/atoms/Icon/Icon.tsx ✨ Create component ./src/components/atoms/Icon/Icon.stories.tsx ✨ Create component ./src/components/atoms/Icon/Icon.spec.tsxこれでめんどくさい作業から開放されました!
- 投稿日:2020-11-13T01:55:54+09:00
【React Native】Invariant Violation "main" has not been registered. This can happen if: *Metro (the local dev server ... の解決法
はじめに
自分の場合はとても処方的なミスでした (react-navigationが関係)
他にもいくつか試した対処法も載せてあります。expoで開発していたら以下の様なエラーが起きた。
Invariant Violation "main" has not been registered. This can happen if: *Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.環境
// app.json { "sdkVersion": "38.0.0" } // package.json "dependencies": { "expo": "^38.0.8", "react-native": "^0.62.2", "react-navigation": "^4.4.3", "react-navigation-stack": "^2.10.0", "react-navigation-tabs": "^2.10.1", }試した対処法
調べてみるといくつか方法があった
1つめ
- watchman watch-del-all
- node_modules & package-lock.json (もしくはyarn.lock) の削除
npm install
(もしくはyarn install
)expo install react-native-safe-area-context
expo start
試してみたが画面は変わらず。。
2つめ
- expoを止めている状態で、
ps aux | grep react-native
を実行して動いているプロセスを探す- 結果が表示されたら、そのプロセスを
sudo kill 'pid'
自分は動いてるプロセスは見つけたものの、killすると
kill:'pid': No such process
と出て解決には至らず。。3つめ
package.jsonのnameとApp.jsonのexpoのnameを同じにする
→ 何も変わらず
自分の解決策
結局めちゃくちゃ初歩的なミスでした。。
react-navigationを使っている部分で、createAppContainer
を呼んでいるが、肝心のimportをし忘れていた為、エラーが起こっていた様です。今回のような場合だけでなく
// ここを書き忘れていた // import { createAppContainer } from "react-navigation"; const AppContainer = createAppContainer(HomeTab);普段こんな場合は
ReferenceError: Can't find variable: Button
とかでエラーが出ると思うのですが。。。importの部分を書き足すと正常に動作しました。
ルーティング周りで変更を加えた場合は、そこの箇所を戻してみると治るかもしれません。
2020/11/14 追記
export default class Index extends React.Component{}この部分を
export default class Index extends React.Component(){}と不要な()をつけてしまった為、同じエラーが起きた。
おそらく特定のパターンに絞れないエラーなので、まずはコードに間違いが無いか確認してみると良いと思います。
メモ
「
expo start --no-dev --minify
で起動すると解決する」
とexpoのForumsにあったので、試してみると確かに一時的に解決した。
Forumsしかしこれはproduction用にアプリをminifyして不要な部分を削っている為、部分的に解決しただけだと思われる。
expo -Development and Production Mode
- 投稿日:2020-11-13T01:42:21+09:00
子供用の学習アプリケーションを作る(1)
はじめに
昨日、筋萎縮性側索硬化症(ALS)と呼ばれる病気についての記事を見かけ、以前より知っている病気ではあったもののなぜ、この病気になってしまうのかについては、知らなかった。
ネットで調べてみたところ、様々なサイトで解説されているものの、言葉が難しかったり、文字数が多く読むのが大変であった。そこで、そのような知識を分かりやすく、まとめ尚且つ大人から子供まで使えるような学習アプリケーションを自作してみました。
実装
まず、環境構築については、下記の記事を見ていただければと思います。
参考: React Nativeをはじめる(環境構築)ディレクトリ構成
使用したUI component, ライブラリ, フリーイラスト
UI component
1.React-native-elements
React-Native-Elementsは、フリーのクロスプラットフォームのUIcomponentです。
色々な開発者が作成したcomponentが集められ、クオリティもかなり高いです。2.React-native-paper
React-native-paperは、使いやすく設計されているUIcomponentです。
componentは、Googleのマテリアル基準に準拠しているのでデザイン性がかなり高いという感想です。ライブラリ
1.React Navigation
React Navigationは、画面遷移のライブラリです。
なぜ、このライブラリが必要かというと、Reactでは画面遷移のための機能が用意されていないからです。React Navigationでは3つの方法で画面遷移ができます。
1.stack:スライドしながら画面遷移する方法
2.tabs:タブを選択することで画面遷移する方法
3.drawer:画面端から現れるメニューで画面遷移する方法今回は、1の方法で実装を行いました。
フリーイラスト
1.manypixels
manypixelsは、フラットなイラストをフリーでdlできます。App.js
このファイルではメインとなるページの処理を記載しています。
App.jsimport 'react-native-gesture-handler'; import * as React from 'react'; import {Image, SafeAreaView, ScrollView, StyleSheet} from 'react-native'; import {Text, Card, Button} from 'react-native-elements'; import {NavigationContainer} from '@react-navigation/native'; import {createStackNavigator} from '@react-navigation/stack'; import AppHeader from './components/header'; import contentsSelect from './components/contentsSelect'; const HomeScreen = ({navigation}) => { return ( <SafeAreaView style={styles.container}> <ScrollView> <AppHeader /> <Text h2 style={styles.hearderMessage}> For explorer who want to know the unknown </Text> <Text style={styles.hearderMessageBody}> ilearnはさまざまなトピックスをまとめ{'\n'}発信する場所だよ。 </Text> <Card> <Card.Title>探検をはじめよう!</Card.Title> <Card.Divider /> <Image source={require('../public/img/teach.png')} style={styles.cardImage} /> <Text style={styles.cardText}> 医学,科学,数学,コンピュータ・サイエンス,宇宙,{'\n'}歴史をまなぼう。 </Text> <Button style={styles.cardButtonText} title="出発する?" onPress={() => navigation.navigate('Contents')} /> </Card> </ScrollView> </SafeAreaView> ); }; const Stack = createStackNavigator(); const App = () => { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="Contents" component={contentsSelect} /> </Stack.Navigator> </NavigationContainer> ); }; const styles = StyleSheet.create({ container: { flex: 1, }, headerImg: { width: 90, height: 30, top: 60, }, hearderMessage: { marginTop: 100, textAlign: 'center', }, hearderMessageBody: { flex: 1, top: 20, marginBottom: 60, textAlign: 'center', fontWeight: 'bold', color: '#93a5b1', }, cardImage: { width: 350, height: 350, }, cardText: { marginBottom: 10, }, cardButtonText: { marginTop: 20, marginBottom: 20, }, }); export default App;header component
名前から察するようにヘッダーについてまとめたファイルになります。
header.jsimport React from 'react'; import {View, StyleSheet, Image} from 'react-native'; const AppHeader = () => { return ( <View> <Image source={require('../../public/img/Header.png')} style={styles.headerImg} /> </View> ); }; const styles = StyleSheet.create({ headerImg: { width: 90, height: 30, marginLeft: 20, top: 30, }, }); export default AppHeader;contents component
こちらのcontents componentは、ユーザが実際に何のコンテンツについて学びたいかを選ばせるページの処理をまとめています。
contentsSelect.jsimport React from 'react'; import {SafeAreaView, ScrollView, StyleSheet} from 'react-native'; import {Card, Title} from 'react-native-paper'; import AppHeader from './header'; const contentsSelect = () => { return ( <SafeAreaView style={styles.container}> <ScrollView> <AppHeader /> <Card style={styles.cardPadding}> <Card.Content> <Title style={styles.cardTitle}>宇宙って?</Title> <Card.Cover source={require('../../public/img/alien.png')} style={styles.cardImg} /> </Card.Content> </Card> <Card style={styles.cardPadding}> <Card.Content> <Title style={styles.cardTitle}>ALSって知ってる?</Title> <Card.Cover source={require('../../public/img/health.png')} style={styles.cardImg} /> </Card.Content> </Card> <Card style={styles.cardPadding}> <Card.Content> <Title style={styles.cardTitle}>Falcon 9がすごい</Title> <Card.Cover source={require('../../public/img/startup_isometric.png')} style={styles.cardImg} /> </Card.Content> </Card> </ScrollView> </SafeAreaView> ); }; const styles = StyleSheet.create({ container: { flex: 1, }, cardImg: { height: 300, }, cardPadding: { marginBottom: 20, }, cardTitle: { fontWeight: 'bold', }, }); export default contentsSelect;動作
次回
次回は、コンテンツ選択した後の詳細画面を作り込んでいこうと思います。
おわり
かなり気合を入れて作成を始めたので、随時記事も更新していこうと思います。
また、React-vativeをさわってみたい方に対し、開発コードがお役に立てば幸いです。参考
React-native
React-native-elements
React Navigation
React-native-paper
manypixels
難病情報センター: ALS
- 投稿日:2020-11-13T00:27:13+09:00
textareaを使わずに複数行文字列入力するのを作ってみた
Twitterのツイート入力するところを眺めて気がついてちょっと驚いたのでメモ程度に
作ったというのもおこがましいレベルの代物ですが…w縦方向に勝手に伸びるのでフォントサイズとか深く気にしなくていいのは便利ですね
やり方
- 超端的に書くとこれだけで出来ます
- ただこのままだとめちゃくちゃ見づらい上に入力しづらいので、適当にCSS当てたほうがいいです。
<span contenteditable="true"></span>デモ
- デモ用のページ を作ってみました
- 無意味に React で作ったのもおいておきます
- ソースコードはこちら
- React * TS でやろうとすると素直に書けないのでびみょいですね…
備考
- 入力値が HTML になるので何かしらのハンドリングをしないと扱いづらいと思います
- 因みに文字選択状態で Ctrl + B とか、 Ctrl + I とかすると装飾がかかりますが、環境によっては多分うまく動きません
- 気になって調べたら TinyMCE はこの方式で実装されてるみたい