はじめに
STAY HOME週間 で家にいる事が多くなり、初めてまともな自炊を始めました。
そこで、自分が作った料理のレシピを投稿するサイトを作りました。
作った物
レシピ投稿サイトです。
キーワードで検索、レシピを全て一覧表示、レシピ投稿の3つの機能があります。
- キーワード検索
レシピをCloud Firestoreに保存する時にタグを1つ以上登録してもらって、それをもとに検索します。検索結果ページより画像をクリックする事でレシピの詳細ページに遷移します。
- 一覧表示
Cloud Firestoreから全て表示します。画像をクリックする事でレシピの詳細ページに遷移します。
- 投稿
画像をCloud Storageに保存して、ダウンロードURLを取得し、それと共に、料理名、材料などの情報をCloud Firestoreに保存します。
環境
node
v12.11.1
create-react-appをインストールしてある
npm install -g create-react-app
React
Reactは公式サイトでは以下のように言われています。 チュートリアルもあるので詳しくは公式サイトを見てみてください。
ユーザインターフェース構築のためのJavaScriptライブラリ
(公式サイトより)
Reactはcreate-react-appというReactアプリの雛形を簡単に作成できる便利な物があります。
以下のコマンドを実行します。
npx create-react-app プロジェクト名 --typescript
--typescript
はオプションでこれをつけるとReact + TypeScriptの環境を構築できます。(つけなくてもReactの環境は構築できます)
作成されたフォルダに移動
cd フォルダ名
実行して動作を確認
npm start
Firebase
FirebaseはmBaasと言われいます。 Googleが提供している包括的なアプリ開発プラットフォームで様々な機能がありますが、以下の3つを利用しました。
Cloud Storage
Cloud Storageはファイルを保存・配信する事ができます。 今回は、ユーザからアップロードされた画像を保存するために用いました。
const storageRef = firebase.storage().ref('images').child(`${postIndex}.jpg`) const snapshot = storageRef.put(image) 以下略
Cloud Firestore
Cloud FirestoreはNoSQLデータベースです。 Cloud Storageにアップロードされた画像のダウンロードURL、ユーザが入力した材料などの情報を 保存するために使用しました。
const downloadURL = await storageRef.getDownloadURL() const db = firebase.firestore() db.collection('tileData').add({ image: downloadURL, title: data.title, 以下略 })
Firebase Hosting
Firebase Hostingはホスティングに用いました。
Material-UI
Material-UIはマテリアルデザインをReactに導入する事ができるUIコンポーネントです。 アプリのデザインを手軽にいい感じにする事ができます。
React Hook Form
フォームバリデーションライブラリです。 ユーザがレシピを入力するフォームにバリデーションをかけました。 公式サイトでは、他のバリデーションライブラリとコードの記述量やレンダリング数を比較してありました。
余談ですが、React Hook FormさんはTwitterでお話しやいいねをしてくれます😄
聞いてすごい!
— 📋 React Hook Form (@HookForm) May 12, 2020
useForm
React Hook FormのAPIです。
useFormを呼び出す事で様々なメソッドを受け取る事ができます。詳しくは公式サイトをご覧ください。
今回は、register
とhandleSubmit
を使いました。
const { register, handleSubmit } = useForm()
register
このメソッドを使用して、フォームにバリデーションルールを登録することができます。
※ Material-UIと併用
<TextField inputRef={register({ required: true })} />
handleSubmit
handleSubmitは、フォームバリデーションに成功するとフォームデータを渡し事ができます。
const onSubmit = (data) => { ....略.... } <form onSubmit={handleSubmit(onSubmit)}> <TextField inputRef={register({ required: true })} /> <button type="submit">Submit</button> </form>
React Router
ルーティングするために用いました。
useHistory
React RouterのHooks APIです。 ページ遷移を行う時にhistoryを取得します。
※ Material-UIと併用
const history = useHistory() <Button onClick={() => history.push('/home'}>
useParams
URLのパスの中で動的に変化する部分の値を取得します。 レシピの詳細ページを1つ用意して、URLに応じて中身を変えています。
おわりに
まだ完全にできた訳ではないので、これからも改良していきたいと思います。
あと、まともに自炊する時間も無くなってきました😅