- 投稿日:2020-10-16T19:35:33+09:00
slackのリアクションを監視してHasura経由でReact画面をリアルタイムに更新する
Slackのメッセージのリアクションを監視して、ReactのUIにリアルタイムに反映させたい。
やることは大きく分けて以下の3つ
- slackのメッセージにおけるリアクションの監視
- 対象メッセージのリアクション回数の更新
- ReactのUIに反映
slackのメッセージにおけるリアクションの監視
slack APIのEvent Subscriptionsを使う。
URLの指定
エンドポイントをここに入力。
今回はFlaskで事前に用意したエンドポイントを利用。
このエンドポイントでslackからjsonを受け取ってHasuraにクエリを投げる。発火条件の指定
Subscribe to events on behalf of usersで発火条件を指定する。
今回は、リアクションが押された時に発火させたいので、以下の二つを有効にする。
- reaction_added
- reaction_removed
これでリアクションがあった時にエンドポイントにjsonが投げられる。
対象メッセージのリアクション回数の更新
Flaskで処理を行う。
今回は、指定のチャンネルのメッセージのリアクションのみ監視したかったため、チャンネル名でフィルターをかける。
次に、受け取ったjsonの中にメッセージのユニークなidが入っているので、これを元にHasuraの方にクエリを投げてリアクション回数を取得する。
その後、reaction_addedかreaction_removedでそのリアクション回数を増減させて最後にmutation。ReactのUIに反映
apollo-clientを使ったsubscriptionは公式documentに沿えばok。
参考
Setting up GraphQL subscriptions using apollo-client
https://hasura.io/docs/1.0/graphql/core/guides/integrations/apollo-subscriptions.html#write-your-subscriptionCreate Subscription and Render Result
https://hasura.io/learn/graphql/react/subscriptions/3-create-subscription/
- 投稿日:2020-10-16T16:14:17+09:00
【ReactNative】ReactNavigationの基本をまとめる
はじめに
ReactNativeで画面を遷移させる際に使う
React Navigation
ですが、様々なpropsが用意されているので、簡単にまとめていきたいと思います。別の画面を指定して遷移させる
定義されたルートの宛先名を指定することで、任意の画面に遷移させることができます。
sample.jsonPress={() => navigate('定義されたルート名', { sampleParam: '任意の引数' }) }ひとつ前の画面に戻る
goBack()
を用いることで、現在表示している画面のひとつ前に戻ることができます。sample.jsonPress={() => goBack()} // ひとつ前の画面に遷移複数個前の画面に戻る
pop()
を用いることで、現在表示している画面の複数個前に戻ることができます。sample.jsonPress={() => navigation.pop(2)} // ふたつ前の画面に遷移ナビゲーション履歴を初期化して遷移する
reset()
を使うことで、ナビゲーション履歴を初期化して遷移することができます。sample.jsonPress={() => navigation.reset({ index: 0, routes: [{ name: 'Home' }], })};
- 投稿日:2020-10-16T09:27:31+09:00
Next.jsのダイナミックルーティングを実装してみた
Next.jsでは、getStaticPaths・getStaticProps・getServerSidePropsといった似た名前の関数が多く違いがわかりづらいですよね...
今回は、その中でも使用頻度の高いgetStaticPaths・getStaticPropsを使用し、ダイナミックルーティングの簡単なサンプルを作成したいと思います。
こちらが今回作成するサンプルの完成形です。
URL:https://nextjs-dynamic.vercel.app/JSONPlaceholderのAPIサーバーを使用し、記事一覧・記事詳細ページを表示しています。
見ての通り、全てのデータが事前ビルドされているため表示が高速です。では、実装までの流れについて説明していきます。
1. ダイナミックルート用のファイル作成
まずは、ダイナミックルート用のファイル(記事詳細ページ)を作成します。
Next.jsでは、pages内でファイル名に[]
を使用することで自動的にダイナミックルート対象となります。/pages/[id].js ├ http://localhost:3000/1 ├ http://localhost:3000/2 └ ...ダイナミックルート用のファイルでは、
getStaticPaths
とgetStaticProps
の関数が必要です。getStaticPaths:ビルド時にレンダリングする必要のあるパスのリストを生成する
getStaticProps:ビルド時に静的なファイルを生成し、ページコンポーネントで使用する値を用意するこれらの関数はクライアント側で実行されることはなく、必ずサーバーサイドで実行されます。
以下は作成した記事詳細ページです。
pages/[id].jsimport Link from 'next/link' // post:getStaticPropsから取得したデータ export default ({ post }) => { return ( <div> <h1>{post.title}</h1> <p>{post.body}</p> <Link href="/"> <a>Back</a> </Link> </div> ) } export const getStaticPaths = async () => { // 外部APIエンドポイントを呼び出しデータ取得 const res = await fetch("https://jsonplaceholder.typicode.com/posts") const posts = await res.json() // 事前ビルドしたいパスを指定 const paths = posts.map((post) => ({ params: { // ファイル名と合わせる ※文字列指定 id: post.id.toString(), }, })) // paths:事前ビルドするパス対象を指定するパラメータ // fallback:事前ビルドしたパス以外にアクセスしたときのパラメータ true:カスタム404Pageを表示 false:404pageを表示 return { paths, fallback: false } } // paramsには上記pathsで指定した値が入る(1postずつ) export const getStaticProps = async ({ params }) => { // 外部APIエンドポイントを呼び出しデータ取得 const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`) const post = await res.json() // ページコンポーネントにpropsとしてに渡す return { props: { post }, } }画面表示までの流れ
- getStaticPathsで、レンダリングする必要のあるパスのリストを生成する
- getStaticPropsで、1で生成したパスのリストから1postsずつAPIエンドポイントを呼び出しデータを取得する
- ページコンポーネントがgetStaticPropsからデータを受け取り、画面に表示される
実際にURLにアクセスしてみると、表示が切り替わることが確認できるかと思います。
2. 記事一覧ページ作成
次に、それぞれの詳細ページにリンクする記事一覧を作成します。
こちらのページに関しても、
getStaticProps
でページコンポーネントで使用する値を事前に用意する必要があります。以下は作成した記事一覧ページです。
pages/index.jsimport Link from 'next/link' // posts:getStaticPropsで取得したデータを受け取る const Home = ({ posts }) => { return ( <div> <h1>記事一覧</h1> <ul> {posts.map((post) => ( <li key={post.id}> {/* リンク先を指定 */} <Link href={`/${post.id}`}> <a>{post.title}</a> </Link> </li> ))} </ul> </div> ) } // ビルド時にデータを取得し静的なファイルを事前に生成 export const getStaticProps = async () => { // 全記事データを取得 const res = await fetch("https://jsonplaceholder.typicode.com/posts") const posts = await res.json() // コンポーネントに渡すデータを指定 return { props: { posts, }, } } export default Home画面表示までの流れ
- getStaticPropsで、画面表示させたいデータを取得する
- ページコンポーネントがgetStaticPropsからデータを受け取り、画面に表示される
以上でダイナミックルーティングの実装完了になります!
おわりに
Next.js公式がSSGを推薦していることもあり、今後さらにダイナミックルーティングを使用する機会が増えていきそうですね!
公式チュートリアルでは、実際にブログを作成しながらダイナミックルーティングについて学ぶことができるので、より詳しく知りたいという方はぜひお試し下さい!
Next.js Dynamic Routes参考資料
Next.js 公式ドキュメント
Next.js 9.3 Released, Improves Static Site Generation
JSONPlaceholder
- 投稿日:2020-10-16T08:38:29+09:00
VSCode + ESLint + Prettier + React + TypeScript (自分用メモ Fall, 2020)
はじめに
- eslint-plugin-prettierが『一般的には非推奨(Prettier公式)』となったのを受けて、リンター&フォーマッター環境を見直す自分用メモ
目標
- React + TypeScirpt のリント
- VSCode保存時にエラーの解消&コード整形
前提
ESLint, Prettier, TypeScript, React のインストール
プロジェクト・フォルダの作成
bash$ mkdir qiita && cd $_ $ yarn init -y yarn init v1.22.10 warning The yes flag has been set. This will automatically answer yes to all questions, which may have security implications. success Saved package.json ✨ Done in 0.04s.ESLint と Prettier
bash$ yarn add -D eslint prettier eslint-config-prettierTypeScript 関連
bash$ yarn add -D typescript @typescript-eslint/{parser,eslint-plugin}React 関連
bash$ yarn add react react-dom $ yarn add -D @types/{react,react-dom} $ yarn add -D eslint-plugin-{react,react-hooks}tsconfig.json
tsconfig.json{ "compilerOptions": { "target": "ES2015", "module": "ES2015", "lib": ["DOM", "ES2015"], "jsx": "react", "strict": true, "moduleResolution": "node", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "baseUrl": ".", "paths": { "*": ["@types/*"] } } }.eslintrc.json
.eslintrc.json{ // 適用する環境 "env": { "es6": true, "node": true, "browser": true, "commonjs": true }, // パーサー "parser": "@typescript-eslint/parser", // jsx を使います "parserOptions": { "ecmaVersion": 2018, "ecmaFeatures": { "jsx": true }, "sourceType": "module" }, // React のバージョンは自動検出に "settings": { "react": { "version": "detect" } }, "plugins": ["react-hooks", "react", "@typescript-eslint"], // 基本的にルールは recommended に従う // prettier 関連は配列の最後尾に書く "extends": [ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "plugin:react/recommended", "plugin:react-hooks/recommended", "prettier", "prettier/react", "prettier/@typescript-eslint" ], "rules": { // TypeScirpt なので prop-types は要らない "react/prop-types": "off" }, // .js ファイルをオーバーライド (webpack.conig.jsなど) "overrides": [ { "files": ["*.js"], "rules": { "@typescript-eslint/no-var-requires": "off", "@typescript-eslint/explicit-function-return-type": "off" } } ] }注意点:
extends
では prettier 関連を配列の最後部に記述すること!.prettierrc.json
prettierのオプションはこちら(少ない!)。
.prettierrc.json{ "singleQuote": true, "jsxBracketSameLine": true }VSCodeの設定
ESLint, Prettier 拡張をインストール
.vscode/settings.json
settings.json{ "editor.formatOnSave": true, // <-- prettierで整形 "editor.codeActionsOnSave": { "source.fixAll.eslint": true // <-- eslintでリント }, // デフォルトフォーマッタをprettierに "editor.defaultFormatter": "esbenp.prettier-vscode" }
editor.defaultFormatter
がキモ?
editor.formatOnSave
でPrettierの整形が効かない時は大抵これを忘れてます。謝々