- 投稿日:2020-03-15T20:58:06+09:00
apollo Clientのcacheに有効期限をつける
はじめに
Apollo Client ver3.0では新たにcacheについていくつか機能が追加されています。その一つがcacheの削除です。
cacheに有効期限を設ける方法について、考えたので備忘録として残します(もっといい方法があれば教えてください)evictとgc
今回は Apollo Client ver3.0で新しく追加されたgcとevictを使います。詳しい説明は公式docを参照してください
evict
evictはcacheに保存されているdataを消すことができます。
使う際は__typenameとidをセットにして使いますcache.evict('__typename:id')gc
gcはevictで特定のdataを消した後cacheに残っているゴミを消すことができます。
ここでいう今回消したdataをrefとして持つ親データです。子を消した事によって、親が参照するdataがなくなりますが、gcを使う事によってこういったゴミを消すことができ、cacheのdataがクリーンに保たれます。cache.gc()実装例
以前挙げたQiitaの記事のQueryで保存されたcacheに有効期限10分をを設定したコードです。(apollo clientの中に有効期限設定できる機能があるのかも?)
import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client"; const link = new HttpLink({ uri: "http://localhost:4000/graphql" }); const cache = new InMemoryCache() const cacheInterval = setInterval(() => { cache.evict('Comment:1'); cache.gc(); }, 10 * 60 * 1000); const client = new ApolloClient({ link, cache, defaultOptions: { watchQuery: { fetchPolicy: "cache-first" } } });
- 投稿日:2020-03-15T20:58:06+09:00
apollo clientのcacheに有効期限をつける
はじめに
Apollo Client ver3.0では新たにcacheについていくつか機能が追加されています。その一つがcacheの削除です。
cacheに有効期限を設ける方法について、考えたので備忘録として残します(もっといい方法があれば教えてください)evictとgc
今回は Apollo Client ver3.0で新しく追加されたgcとevictを使います。詳しい説明は公式docを参照してください
evict
evictはcacheに保存されているdataを消すことができます。
使う際は__typenameとidをセットにして使いますcache.evict('__typename:id')gc
gcはevictで特定のdataを消した後cacheに残っているゴミを消すことができます。
ここでいう今回消したdataをrefとして持つ親データです。子を消した事によって、親が参照するdataがなくなりますが、gcを使う事によってこういったゴミを消すことができ、cacheのdataがクリーンに保たれます。cache.gc()実装例
以前挙げたQiitaの記事のQueryで保存されたcacheに有効期限10分をを設定したコードです。(apollo clientの中に有効期限設定できる機能があるのかも?)
import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client"; const link = new HttpLink({ uri: "http://localhost:4000/graphql" }); const cache = new InMemoryCache() const cacheInterval = setInterval(() => { cache.evict('Comment:1'); cache.gc(); }, 10 * 60 * 1000); const client = new ApolloClient({ link, cache, defaultOptions: { watchQuery: { fetchPolicy: "cache-first" } } });
- 投稿日:2020-03-15T19:44:05+09:00
GatsbyとGitHub PagesとGitHub Actionsで技術系イベントサイトを無料・爆速で作る方法
技術系イベントサイト用に以下を作成しました。
このサイトは以下のことができます。
- React製静的サイトジェネレータGatsbyでサイトを生成
- @lekoarts/gatsby-theme-minimal-blogテーマを利用
- イベント告知、ブログ記事を追加・Markdownにより編集可能
- GitHub Pagesでサイト公開
- GitHub Actionsによりmasterからgh-pagesブランチに自動デプロイ
コミュニティベースでハッカソンやアイデアソンなど技術系イベントを開催するときに、結構イベントサイト作るのに費用や時間がかけられないことがあると思います。これを使えば、無料でかつ爆速でサイト立ち上げられます。その方法を以下で説明します。
どのようなサイトができるかは、一番最後の公開事例を見てください。
準備
まず、uedayou/event-page-gatsbyを自分のGitHubアカウントにフォークして、自分のアカウント内のリポジトリを clone してください。
$ git clone https://github.com/[あなたのアカウント名]/event-page-gatsby.git
event-page-gatsby
ディレクトリに移動して、npm install
を実行します。$ cd event-page-gatsby $ npm installインストールが終わったら、
npm run develop
を実行して、サイトが生成されるか確認します。$ npm run develop
localhost:8000
をブラウザでアクセスして、Webページが表示されれば成功です。
npm run develop
が実行中であれば、編集された内容がすぐにブラウザに反映されます。編集
このサイトにはヘッダー部、イベント告知部、ブログ部、フッター部の4つから構成されています。それぞれの編集部分について説明します。デモサイトを見ながら、読むとわかりやすいと思います。
ヘッダー部
ヘッダー部については、
gatsby-config.js
を編集します。gatsby-config.jsmodule.exports = { pathPrefix: "/event-page-gatsby", siteMetadata: { siteTitle: `技術系イベントページ`, siteTitleAlt: `技術系イベントページ`, siteHeadline: `技術系イベントページ`, // Will be used to generate absolute URLs for og:image etc. siteUrl: `https://uedayou.github.io/event-page-gatsby/`, // Used for SEO siteDescription: `技術系イベントで便利に利用できるGatsbyで作られたサイトです。`, // Will be set on the <html /> tag siteLanguage: `ja`, // Used for og:image and must be placed inside the `static` folder siteImage: `/banner.jpg`, // Twitter Handle author: `@uedayou`, // ここでサイトのライセンスを規定できます。たとえば、No rights reserved など siteLicense: `All rights reserved`, // ここでブログ部分のタイトルを指定できます。 blogLabel: `ブログ`, // ここでタグ部分のタイトルを指定できます。 tagsLabel: `タグ`, }, ...
siteTitle
,siteTitleAlt
,siteHeadline
,siteUrl
,siteDescription
など適宜書き換えてください。
もし、サイトコンテンツのライセンスをオープンデータにしたい場合は、siteLicense
を書き換えてください。我々のサイトでは、No rights reserved
(パブリックドメイン)としています。
siteImage
で指定する画像などサイト内で利用したいスタティックファイル(サイトのアイコン等)は、static
ディレクトリにコピーすればアクセスできます。
pathPrefix
は、サイト内での絶対パスを指定してください。例えば、https://uedayou.github.io/event-page-gatsby/
の場合、/event-page-gatsby
を指定します。独自ドメインを使用する(例えば、https://iodd2020osaka.lodosaka.jp/)であれば、/
を指定してください。この設定が間違っていると、サイト内リンクがすべてリンク切れになりますので、注意してください。右側の3つのリンク部分は以下を編集すると変更されます。
gatsby-config.js... externalLinks: [ { name: `GitHub`, url: `https://github.com/uedayou/`, }, { name: `このリポジトリ`, url: `https://github.com/uedayou/event-page-gatsby`, }, { name: `個人ページ`, url: `https://uedayou.net/`, }, ], }, ...イベント告知部
イベントの告知は、
src/@lekoarts/gatsby-theme-minimal-blog/texts/hero.mdx
ファイルを編集します。hero.mdx技術系イベントの告知部分として使えます。 #### この部分を編集するには 「src/@lekoarts/gatsby-theme-minimal-blog/texts/hero.mdx」 上記ファイルを編集してください。 Markdownにより編集できます。 #### 実際に使用しているページ [インターナショナル・オープンデータ・デイ 2020 大阪](https://iodd2020osaka.lodosaka.jp/) サンプルとして参照してください。Markdownで記述できます。
ブログ部
本サイトには、ブログ機能があります。我々のイベントでは、情報提供を集約するサイトとして使用していますので、ブログ部分に提供された情報をまとめることとしました。
例えば、ハッカソンやアイデアソンでは、各チームの成果をチーム自身でブログ部分にまとめてもらい、プルリクエストを募れば、成果をまとめることをチームに一任することができるでしょう。ブログは、
content/posts/
以下に追加していきます。
まず、記事単位でディレクトリを作ります。数字から始まるディレクトリは受け付けてくれないようなので、半角英字から始まるようにしましょう。そのディレクトリの中にindex.mdxファイルを作ります。index.mdxファイルを以下のようなフォーマットで記述すれば、ブログ記事が追加されます。index.mdx--- title: "ここにタイトルを指定します" date: 2020-03-14 tags: - サンプル - テスト ページ slug: "/path-of-this-post" --- ### ブログ部分の使い方 上記の、title, date, slug を指定してください。 tags はなくてもかまいません。slug がないと、title がパス名となります ブログリストのタイトルは、gatsby-config.js の 「siteMetadata.blogLabel」 により変更できます。
title
,date
,slug
(ブログ記事のパス)が指定されていれば後は、記事をMarkdownで書くだけです。フッター部
この部分は、
src/@lekoarts/gatsby-theme-minimal-blog/texts/bottom.mdx
を編集します。
我々のイベントでは、関連するリンク集として使いました。bottom.mdx<Title text="リンク" /> - [個人ページ](https://uedayou.net/) - [GitHub](https://github.com/uedayou) - [このリポジトリ](https://github.com/uedayou/event-page-gatsby)
<Title text="リンク" />
のリンク
を変えれば、セクション名も変わります。ここは、それぞれ自由に変更して、用途に合わせて使ったほうがいいと思います。まだ、細かいところはありますが(随時追加したいと思います)、上記を編集すれば、最低限体裁の整ったサイトはすぐ作れます。サイト作成に時間がかけられない、という場合、結構あると思いますが、是非使ってください。技術系や、イベントのみならず、すべてがシンプルなので、いろいろ使い道はあると思います。
サイト公開
ここまでの編集が終わったら、サイト公開の準備をしましょう。編集内容を
git push
する前にまず、GitHubリポジトリのSettingsページでサイトをGitHub Actionsを利用して自動公開できるように設定しましょう。この設定は一度行えば、以後設定する必要はありません。秘密鍵・公開鍵作成
このサイトを自動的に公開するためには、秘密鍵と公開鍵が必要になります。
まず、鍵を作成します。$ ssh-keygen -t rsa -b 4096 -C "$(git config user.email)" -f gh-pages -N ""※ Linux, Macのみ
ここで、秘密鍵(
gh-pages
)と公開鍵(gh-pages.pub
)の各ファイルが作成されます。
そのほかの方法は、こちらを参照してください。
GitHub Actionsを利用したGitHub Pagesのデプロイは以下の記事の方法を利用しています。GitHub Actions による GitHub Pages への自動デプロイ
公開鍵を登録
Settings > Deploy Keys
ページを開き、公開鍵を追加(Add deploy key
)します。
Title
に任意の公開鍵の名前、Key
に先ほど作成したgh-pages.pub
をテキストエディタで開き、文字列をすべてコピーして、貼り付けます。
Allow write access
にチェックを入れて、Add key
ボタンを押してください。秘密鍵を登録
秘密鍵は
Settings > Secrets
で設定します。
Title
にACTIONS_DEPLOY_KEY
と入力してください。
(※この名前以外では自動デプロイされません)
Value
に公開鍵と同じく、gh-pages
をテキストエディタで開き、文字列をすべてコピーして貼り付けてください。
Add secret
ボタンを押せば完了です。サイト更新作業
公開鍵、秘密鍵の設定が終われば、
git push origin master
で更新内容をpushしましょう。
masterブランチにpushされれば、GitHub Actionsが自動的にGitHub Pagesの作成・更新を行います。GitHub Actions のページでその処理の流れを確認できます。
以下のようになれば、更新は完了です。https://[あなたのアカウント名].github.io/event-page-gatsby/
を開いてみてください。ページが表示されるはずです。
その他
独自ドメインでの運用は、通常と同じ方法で可能です。
CNAME
ファイルはstatic
ディレクトリに入れてpushすれば反映されます。GitHub Pages サイトのカスタムドメインを管理する
公開事例
uedayou/event-page-gatsbyは、2020年3月7日~3月17日まで開催されるインターナショナル・オープンデータ・デイ 2020 大阪のイベントサイトとして作成したものです。
- 投稿日:2020-03-15T17:48:23+09:00
Material-UIでコンポーネントの色を変更する方法まとめ[React+Typescript]
はじめに
フロントまだまだよくわからないけれど、React+Typescript+Material-uiを使って、かっこいいWebアプリを作ろうとしてつまずいている初心者がMaterial-UIでコンポーネントの色を変えようとして四苦八苦したので、そのまとめです。
公式のドキュメントやサンプルコードを参考に色を変える方法として以下の3つでまとめました。
- Material-uiのPaletteを使う方法
- Paletteの色を変えたい
- style属性を使う方法
- className属性を使う方法
今回は以下のSimple App Barの色を変更していきます。
公式のサンプルコードはこちらです。変更していくコードの概要
今回は説明の都合上、以下のコマンドを実行して、そのままApp.tsxを変更していきます。
npx create-react-app learn-material-ui --typescript // material-uiのパッケージのインストール yarn add @material-ui/core yarn add @material-ui/iconsバージョンなどは以下です。
node.js:v10.16.0 "@material-ui/core": "^4.9.5", "@material-ui/icons": "^4.9.1"App.tsxを公式のサンプルコードを参考に以下のように書き換えます。
これで実行すると上で紹介したスクリーンショットのようになります。import React from "react"; import "./App.css"; import { createStyles, makeStyles, Theme } from "@material-ui/core/styles"; import AppBar from "@material-ui/core/AppBar"; import Toolbar from "@material-ui/core/Toolbar"; import Typography from "@material-ui/core/Typography"; import Button from "@material-ui/core/Button"; import IconButton from "@material-ui/core/IconButton"; import MenuIcon from "@material-ui/icons/Menu"; const useStyles = makeStyles((theme: Theme) => createStyles({ root: { flexGrow: 1, color: "#388e3c", backgroundColor: "#81c784" }, menuButton: { marginRight: theme.spacing(2) }, title: { flexGrow: 1, textAlign: "center" } }) ); function App() { const classes = useStyles(); return ( <div className={classes.root}> <AppBar position="static"> <Toolbar> <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu" > <MenuIcon /> </IconButton> <Typography variant="h6" className={classes.title}> News </Typography> <Button color="inherit">Login</Button> </Toolbar> </AppBar> </div> ); } export default App;Material-uiのPaletteを使う方法
一番単純な
AppBar
のcolor
を利用する方法を紹介します。
コードの変更箇所は単純で以下のようにAppBar
タグにcolor
を追加するだけです。<AppBar position="static" color="secondary">公式のドキュメントによると、
AppBar
のcolor
は以下の要素に対応しているそうです。
default
inherit
primary
secondary
transparent
「いやいや、この要素どれがなんなのかさっぱりわからないよ……」となったので、自分なりに調べてみたり実行したりした結果が以下です。
ちなみにブラウザの検証のElements
でAppBar
の中を見ると、cssの中身が分かります。
inherit
:親要素のcolor
をinherit
(サンプルコードでは親要素のdiv
に設定していたcolor: "#388e3c"
が継承されました)
primary
:デフォルトでしていされている。material-uiが用意しているDefault Themeのpalette
のprimary
secondary
:material-uiが用意しているDefault Themeのpalette
のsecondary
このなかの
primary
とsecondary
はmaterial-uiで色に統一感を持たせるためのPaletteというものの1つです。
様々なコンポーネントで利用されていて、コンポーネントごとに利用できるものが異なります。
デフォルトでは以下のような色が設定されています。
この色を変更する方法を次に紹介します。
Paletteの色を変えたい
アプリのイメージカラーで統一したいといったときに
createMuiTheme
とThemeProvider
を利用します。
公式ページを参考にしつつ、コードを以下のように変更してみました。import React from "react"; import "./App.css"; import { createStyles, makeStyles, Theme } from "@material-ui/core/styles"; import AppBar from "@material-ui/core/AppBar"; import Toolbar from "@material-ui/core/Toolbar"; import Typography from "@material-ui/core/Typography"; import Button from "@material-ui/core/Button"; import IconButton from "@material-ui/core/IconButton"; import MenuIcon from "@material-ui/icons/Menu"; import { createMuiTheme } from "@material-ui/core/styles"; import { teal } from "@material-ui/core/colors"; import { ThemeProvider } from "@material-ui/styles"; const useStyles = makeStyles((theme: Theme) => createStyles({ root: { flexGrow: 1, color: "#388e3c", backgroundColor: "#81c784" }, menuButton: { marginRight: theme.spacing(2) }, title: { flexGrow: 1, textAlign: "center" } }) ); // 追記 const theme = createMuiTheme({ palette: { primary: { main: teal[500] }, secondary: { main: "#00bcd4" } } }); function App() { const classes = useStyles(); return ( <ThemeProvider theme={theme}> // 追記 <div className={classes.root}> <AppBar position="static" color="primary"> <Toolbar> <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu" > <MenuIcon /> </IconButton> <Typography variant="h6" className={classes.title}> News </Typography> <Button color="inherit">Login</Button> </Toolbar> </AppBar> </div> <div className={classes.root}> <AppBar position="static" color="secondary"> <Toolbar> <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu" > <MenuIcon /> </IconButton> <Typography variant="h6" className={classes.title}> News </Typography> <Button color="inherit">Login</Button> </Toolbar> </AppBar> </div> </ThemeProvider> // 追記 ); } export default App;すると以下のように色を変更したAppBarを2つ表示することができました。
ちなみに
@material-ui/core/colors
で、Materialデザインの色を利用することができます。
色の一覧はこのページを参照してみてください。style属性を使う方法
以下のように
AppBar
タグを変更します。<AppBar position="static" style={{ color: "#e0f2f1", backgroundColor: "#004d40" }}>すると、以下のように色を変更することができます。
className属性を使う方法
まず、以下のように
useStyles
を書き換えます。const useStyles = makeStyles((theme: Theme) => createStyles({ root: { flexGrow: 1, color: "#388e3c", backgroundColor: "#81c784" }, bar: { color: "#e0f2f1", backgroundColor: "#004d40" }, menuButton: { marginRight: theme.spacing(2) }, title: { flexGrow: 1, textAlign: "center" } }) );次に
AppBar
タグを以下のように変更します<AppBar position="static" className={classes.bar}>すると、以下のようにstyle属性を使う方法と同じく書き換えることができます。
おわりに
Material-UIでコンポーネントの色を変える方法をまとめました。
Material-UI、とても便利なので使いこなしていきたいですね…!
また、わかったことなどありましたら、まとめていきたいと思います。
- 投稿日:2020-03-15T17:02:30+09:00
Reactのフックの使い方①
初心者のためのReact Hooks
なるたけ分かりやすく解説してみます。
話す内容
以下の流れで、話していきます。
1:フックとは?
2:簡単な使い方(useState)
3:API連携する際の使い方(useState)(Reactのフックの使い方②で解説します。)3までいけば、実用的な使い方を少し習得できるかと思います。
フックとは?
そもそもフックの導入は、React16.8以降からの機能で、stateなどの機能をclass型ではなく、function型で書けるようになったというのが始まりです。今まで、componentDidMount, componentDidUpdate, componentWillUnmountと書きまくって、ライフサイクルメソッドを通していたものが、フック使っちゃえばそれら無くてもOKや!となるのです。結果として、コードがより短くなります。
使う際は、
import React, { useState } from 'react';
などと書いて、使うことができます。フックの種類は、カスタムフック(自分で作れちゃうオリジナルのフックのこと)をのぞいて、10種類あります。全て、必ずuseXXXから始まります。カスタムフックもuseXXXとするのが一般的です。
基本のフック
・useState
・useEffect
・useContext追加のフック
・useReducer
・useCallback
・useMemo
・useRef
・useImperativeHandle
・useLayoutEffect
・useDebugValueその中でも、基本のフックが上3つ(useState, useEffect, useContext)なので、これは最初に使えるようにしましょう。ただ、今回の記事ではuseStateに絞って解説していきます。一つ分かれば、後はスラスライケるかと思います。
簡単な使い方
説明だけ見てても、意味ないので早速使っていきましょう。
使うのは、codesandboxにすることとします。https://codesandbox.io/s/wizardly-borg-jt7j4
すでに、上のリンクには、ReactとuseStateの記述がされているので、即時にフックが使えます。
実際に、以下からフックスの説明に入っていきます。
useStateの導入
まず、1行目ですが、{ useState }となっております。これは、useXXXが、React側で宣言されている関数であるため、その関数を使うことを表記するために{}を使って、導入しています。
押すとカウントが増えるボタンを作る
今回作るのは、簡単なカウント型のボタンの作成です。たった13行ですので、ささっと見ていきましょう。
import React,{useState} from "react"; import "./styles.css"; export default function App() { return ( <div className="App"> </div> ); }今、このようなfunction型の表記があります。
まず、必要なのは、今回使うuseStateに現在の state の値と、それを更新するための関数とをペアにして返すことです。export default function App() { const [count, setCount] = useState(0); return ( <div className="App"> </div> ); }const ~ の部分を追加しました。ここでは、state変数を宣言しています。第一引数のcountは、その時々での状態を保持してくれるものです。第二引数のsetCountは、更新してくれるための関数です。
useState(0)の部分は、stateの初期値です。ざっと書いていますが、countは常に表示されている、setCountは常に状態を変更してくれると考えてください。この2つは常にペアです。次に、中身の部分を作っていきます。
<div className="App"> <p>You clicked {count}times</p> <button onClick={()=>setCount(count + 1)}>click me</button> </div>{count}の部分は、毎回button内にあるonClickメソッドが押されるたびに1ずつ増えていきます。今回、buttonが押されると、表示が変わる部分は、この{count}部分のみです。
onClick={()=>setCount(count + 1)}
ここの意味としては、クリックされたらsetCount内にあるものを実行するよということです。
setCount内には、(count + 1)とあります。今回、
const [count, setCount] = useState(0);のように、useState(0)、つまり初期値を0としているため、0 + 1となり2が表示されます。これがもし、useState(5)となっていれば、初期値5 + 1となり6を返します。
完成したのは以下のようなモノです。
https://codesandbox.io/s/infallible-chatterjee-lb91eまとめ
ReactのuseStateについて説明してみました。
次回は、Reactのフックの使い方②で、簡単なAPI実装を含めたフックの使い方を解説したいと思います。
- 投稿日:2020-03-15T16:28:43+09:00
グローバルなステートをめっちゃシンプルに扱えるReactN
Reactでグローバルなステートを扱う場合、
Reduxを使用するのが主流かと思いますが、
ReactN
というライブラリによって、グローバルなステートをめっちゃシンプルに扱えたので、めっちゃシンプルに紹介します。「めっちゃシンプルに扱えた」という表現をもう少し具体的な表現にすると、
「ちょっとだけ初期設定をしたら、useState
を使うノリでグローバルなステートを使えた」
という感じです。ReactNを使用したサンプル
サンプル(CodeSandBox)
各ページで単一のstateとsetStateを使用しています。
上記のサンプルはTypeScript
と、ページ遷移にreact-router-dom
を使用しています。ReactNの使い方
インストール
npm i reactnまたは、
yarn add reactnちょっとだけ初期設定
- index.tsxで、グローバルに使いたいstateの名前と初期値を、下記のように設定します。
import React, { setGlobal } from "reactn"; // 'from "reactn"'で、Reactの諸機能とReactNの諸機能をまとめてインポートできます。 setGlobal({ count: 0 }); // setGlobal({ stateの名前: 初期値 })ReactNのGitHubの
README.md
に、「ReactDOM
のレンダー前にsetGlobal
をするのがオススメ」と書かれているので、サンプルではそれに従っています。
- global.d.tsで、グローバルステートの型を下記のように定義します。
import "reactn"; declare module "reactn/default" { export interface State { count: number; } }初期設定は以上です。
あとはuseState
を使うノリで、グローバルステートを扱えます。グローバルステートを扱う
グローバルステートを使いたいコンポーネントで下記のように記述すると、グローバルなステートを扱えます。
import { useGlobal } from "reactn"; const [count, setCount] = useGlobal("count"); // useGlobal("setGlobalで設定したstateの名前")上記の通りグローバルステートの扱い方が、
const [count, setCount] = useState(0);
のような扱い方とほぼ同じではないでしょうか。また、
const count = useGlobal("count")[0]; // stateだけを使う const setCount = useGlobal("count")[1]; // setStateだけを使う上記のようにグローバルステートを扱うこともできます。
以上がReactNを利用したグローバルステートの扱い方です。
ReactNの"N"の正体
「ReactNの"N"はなんだろな」と思ったので、ReactNのREADMEやIssuesやReactNの記事を読み漁ったのですが、答えを見つけることができませんでした。
なので、ReactNの作者であるCharles Stoverさんに「"N"ってなんですか」と伺ったところ、下記のニュアンスの返答をいただきました。
ReactNは「より多くの機能を備えたReact」にしたかった。
そこで「Reactに足りない部分までカバーする」→「"React"に足りない部分"ion"(Reactの由来はReaction)までカバーする」という命名コンセプトを思いつき、"Reacti"や"Reactio"という名前にしようとしたが、いずれも既に使われていた。
それで"ReactN"という名前にいきついた。
だから"N"は何かの略ではない。平たくしてまとめると、
「"Reaction"に対してはReactは"React"までだから、オレのライブラリはその先の"ion"まで届いてみせるぜ!」
ということかと思います。
些細な質問に答えてくださったことと、ReactNという素敵なライブラリを制作していただいたCharles Stoverさんに、謝意を申し上げます。
参考記事・関連リンク
- 投稿日:2020-03-15T15:48:30+09:00
Reactのエレメントについてかなりザックリ解説する
Reactのエレメントとは
Reactはコンポーネントとという小さいパーツを複数組み合わせることでUIを構築しています。またコンポーネントは直接使用するのではなく、インスタンス化(設計図であるクラスを元にオブジェクトであるモノを生成すること)することで使用します。このインスタンス化によって生まれたオブジェクトをエレメントと呼びます。
またこの記事ではコンポーネント、エレメント、バーチャルDOMについて非常にわかりやすく解説がされています。
- 投稿日:2020-03-15T13:26:27+09:00
Next.jsをGCP Cloud Run上で実行する方法
Next.jsのチュートリアルをGCP Cloud Run上で動かすための方法をメモ。
概要
- Next.JSの6 fetching dataチュートリアルをやる
- Docker 化する
- Cloud Container Registryにpushする
- Cloud Runにdeployする
- アクセスして動ていることを確認
next.jsのtutorialをcloneする
git clone https://github.com/zeit/next-learn-demo.gitTutorialをやる
今回はserverless設定を試したかったので、
6-fetching-data
を使います。cd next-learn-demo/6-fetching-data
Tutorial自体は下記を見ながらやってください。
https://nextjs.org/learn/basics/fetching-data-for-pages詳細の説明は省きますが、映画情報APIから情報をとってきて成形するチュートリアルになってます。
Docker化する
手元の環境に合わせてnode12でDokcerコンテナを作ります。
DockerfileFROM node:12.16.1-alpine WORKDIR /app ENV PATH /app/node_modules/.bin:$PATH COPY . . RUN npm install && npm run build # start app CMD [ "npm", "run", "start" ]Cloud Run用に公開するポートを指定する
Cloud Runは
PORT
環境変数が公開されることを期待するので、package.jsonを書き換えます。
"start": "next start -p ${PORT}"
がミソ。package.json{ "name": "hello-next", "version": "1.0.0", "scripts": { "dev": "next", "build": "next build", "start": "next start -p ${PORT}" }, "license": "ISC", "dependencies": { "isomorphic-unfetch": "^3.0.0", "next": "latest", "react": "^16.12.0", "react-dom": "^16.12.0" } }ここで、いったんちゃんと動くか試しておくと良さそうです。
shusaku-next-cloudrunは適当な名前なので好きな名前を付けてください。docker build . -t shusaku-next-cloudrun:latest PORT=8080 docker run -p8080:${PORT} shusaku-next-cloudrunlocalhost:8080にアクセスしてレスポンスがあればOKです。
Cloud Registryへ登録
Buildしたdockerにtagを打って、Cloud Registryへ登録します。google cloud sdkはインストールしておいてください。
docker tag shusaku-next-cloudrun gcr.io/${PROJECT_NAME}/shusaku-next-cloudrun:latest docker push gcr.io/${PROJECT_NAME}/shusaku-next-cloudrun:latestCloud Runへdeploy
この時いくつかコツがあります。
- --allow-unauthenticated を付けておくと、デプロイした後に振られたURLで動作確認できます。
- --projectはなくても動きますが、複数のprojectをgcloudコマンドで使っていると、defaultのconfigを読みに行ってしまってうまくいきません
- 初めて実行する場合は、認証情報に関するエラーが出るので
gcloud auth configure-docker
を実行する必要があるかも。gcloud beta run deploy --image gcr.io/${PROJECT_NAME}/shusaku-next-cloudrun --project ${PROJECT_NAME} --platform managed --allow-unauthenticatedBrowserからアクセス
URLが最後表示されるのでそこからアクセスしたらOK
- 投稿日:2020-03-15T12:32:49+09:00
Reactの環境構築
【React】npxでのReactの環境構築までのステップについて
create-react-appコマンドを使用
※注意事項:事前にnode.jsをインストールしてください。
まだインストールされていない方はこちらから!
→node.js1.ターミナルでコマンドを実行
①"ls"コマンドを入力してディレクトリがすでに存在しているかの確認をします。
例)react-directory(お好きな名前)をディレクトリ名とする。②"npx create-react-app react-directory"と入力をします。
2.実行結果を確認
実行完了後、"ls"コマンドを入力して"react-directory"が実行できていることを確認します。
3.packge.jsonを確認
①ダウンロードされたディレクトリにpackage.jsonがあることを確認します。
4."npm start"でReactアプリを起動
エディタで"npm start"を入力してURLを出力する。
5.環境構築成功
エディタで出力されたURLをクリックして画像のように表示されれば成功です。
お疲れ様でした!
- 投稿日:2020-03-15T12:32:49+09:00
【React】npxでのReactの環境構築までのステップについて
create-react-appコマンドを使用
※注意事項:事前にnode.jsをインストールしてください。
まだインストールされていない方はこちらから!
→node.js1.ターミナルでコマンドを実行
①"ls"コマンドを入力してディレクトリがすでに存在しているかの確認をします。
例)react-directory(お好きな名前)をディレクトリ名とする。②"npx create-react-app react-directory"と入力をします。
komorioBookpuro:~ komorishuhei$ npx create-react-app react-directory npx: 99個のパッケージを5.733秒でインストールしました。 Creating a new React app in /Users/komorishuhei/reac-directory. Installing packages. This might take a couple of minutes. Installing react, react-dom, and react-scripts with cra-template...2.実行結果を確認
実行完了後、"ls"コマンドを入力して"react-directory"が実行できていることを確認します。
Success! Created react-directory at /Users/komorishuhei/react-directory Inside that directory, you can run several commands: npm start Starts the development server. npm run build Bundles the app into static files for production. npm test Starts the test runner. npm run eject Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can’t go back! We suggest that you begin by typing: cd react-directory npm start Happy hacking!3.packge.jsonを確認
①ダウンロードされたディレクトリにpackage.jsonがあることを確認します。
②package.jsonの中身をエディターで確認します。
{ "name": "react-directory", "version": "0.1.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.5.0", "@testing-library/user-event": "^7.2.1", "react": "^16.13.0", "react-dom": "^16.13.0", "react-scripts": "3.4.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } }4."npm start"でReactアプリを起動
エディタで"npm start"を入力してURLを出力する。
Compiled successfully! You can now view project in the browser. Local: http://localhost:3000 On Your Network: http:// Note that the development build is not optimized. To create a production build, use npm run build.5.環境構築成功
エディタで出力されたURLをクリックして画像のように表示されれば成功です。
お疲れ様でした!
- 投稿日:2020-03-15T11:47:59+09:00
[React]Hooks を使って無限スクロールを実装する
Reactでいろんなサンプルを作って理解しようとしてるんですが、その中で無限スクロールを作ってみたので Memo
![]()
サンプルは こちら
サンプルの API はこちらの API を使わせてもらいました。
https://punkapi.com/import React, { FC, useEffect } from 'react'; // setPageNumber でページを変えると fetch してくる hook。取得してきたものは beers にたまっていく import useBeers from 'hooks/useBeers'; import lodash from 'lodash'; const InfiniteScroll: FC = () => { const { beers, setPageNumber } = useBeers(); // 一番下に到達したら setPageNumber でページを更新 const handleScroll = lodash.throttle(() => { if ( window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight ) { return; } setPageNumber(prev => prev + 1); }, 200); useEffect(() => { window.addEventListener('scroll', handleScroll); return () => { window.removeEventListener('scroll', handleScroll); }; }, []); // eslint-disable-line react-hooks/exhaustive-deps return ( <> <ul> {beers.map((beer: any) => ( <li key={beer.id}> <img src={beer.imageSrc} /> <div>{beer.title}</div> </li> ))} </ul> </> ); }; export default InfiniteScroll;
- 投稿日:2020-03-15T11:37:53+09:00
パパメモ
メモを保存するときの画面流れ
メモを書く
「貼り付ける」ボタンを押す
冷蔵庫に貼り付けられる貼り付けたメモを押す
拡大して表示される
- 投稿日:2020-03-15T03:59:17+09:00
styled-components + TypeScript�でコンポーネントが拡張できなかった
今回の問題
コンポーネントを作成して別ファイルにインポートして拡張したかったができなかった。
Paragraph.tsxconst Paragraph = styled.p` color: red; ` export default Paragraphこんなコンポーネントを作成した。
これをApp.tsx
にインポートして拡張しようとしてこんな風にした。App.tsximport Paragraph from 'Paragraph' const StyledParagraph = styled(Paragraph)` color: blue; ` export default () => { return ( <StyledParagraph>hoge</StyledParagraph> ) }理想の結果:hoge
実際の結果:hogeなぜ青くならない…。
原因と解決方法
原因は元になるコンポーネントに拡張後のクラス名が反映されていなかった。
<p class="Paragraphのクラス名 StyledParagraphのクラス名">hoge</p>
こうなってほしいのにdeveloperToolで確認すると
<p class="Paragraphのクラス名">hoge</p>
こうなっていたのが原因だった。そのため、
Paragraph.tsx
でStyledParagraphのクラス名
を受け取れるようにすればいいので、Paragraph.tsx
を以下のように書き換えた。Paragraph.tsxinterface propsInterface { className?: string } const Paragraph = styled.p` color: red; ` const paragraph = (props: propsInterface) => { return <Paragraph className={props.className} /> } export default paragraphこうすることで拡張した後のstyleを反映させることができた。
実際の結果:hoge
あとがき
これがスマートで正しい解決策なのかは分からないが自分は解決することができたので、もし解決してない人がいれば参考にしてほしい。
- 投稿日:2020-03-15T01:21:15+09:00
React Material-UI Snackbarのカスタマイズに挑戦した
前提
React Material-UIのSnackbarコンポーネントアニメーションを自分好みにカスタマイズしてみまました。
React × Material-UIの記事が少ないので、内容コアですが、記事にしてみました。Snackbar(スナックバー)とは
スナックバーは、実行プロセスをユーザーに通知するための表現です。
こちらのスライドアニメーションのカスタマイズに挑戦します。
Snackbarコンポーネントの構造
Material-UIの構造の多くは、atom要素を構成しています。
今回のSnackbar
も同様に、複数のatom要素でできています。ReactのChrome拡張ツールなどでコンポーネント構造を見ると以下のようになっています。
<Snacbar> <ClickAwayListener> <Transition> <Slide> // デフォルトは<Grow> <SnackbarContent>もちろん、利用時に、テキスト構造など
Snackbar
のコンポーネント内に渡してあげると構造は変化します。APIについて
Snackbar
コンポーネントに用意されたコンポーネントは主に以下があります。(公式サイト)
- action
- スナックバーの最後にレンダリングされる要素
- anchorOrigin
- アンカー要素
- autoHideDuration
- スナックバーの表示時間
- message
- スナックバーに表示されるメッセージ
- onClose
- 閉じるリクエストが起こった場合のコールバック
- open
- 表示
- TransitionComponent
- トランジションに使用されるコンポーネント
- TransitonProps
- トランジション要素のプロパティ
- transitonDuration
- トランジション期間の設定
Snackbarの実装
特別な要素指定を行わずに
Snackbar
の組み込みをしてみました。import React from 'react'; import Button from '@material-ui/core/Button'; import Snackbar from '@material-ui/core/Snackbar'; import Slide from '@material-ui/core/Slide'; import ClearIcon from '@material-ui/icons/Clear'; // FIXME:せっかくTransitionPropsプロパティあるのでそちらでdirection設定したい... function Transition(props) { return <Slide {...props} direction="left" />; } export default function App() { const [open, setOpen] = React.useState(false); const handleOpen = () => { setOpen(true); }; const handleClose = () => { setOpen(false) }; return ( <div className="App"> <Button variant="contained" onClick={handleOpen}>Register</Button> <Snackbar open={open} message="Complete!" onClose={handleClose} TransitionComponent={Transition} action={<ClearIcon onClick={handleClose}/>} /> </div> ); }
TransitionProps
がよくわからない
Slide
コンポーネントの組み込み方が気持ち悪いですが、なせか、TransitionProps
がうまく効きませんでした...
(原因わかったり、対応方法見つけたらまたそのタイミングで...わかる方いましたらコメントいただけると嬉しいです。。)コードについて
Button
コンポーネントの押されたタイミングでスナックバーが表示されます。
Snackbar
のaction
に閉じるアイコンを設置してonClick
イベントでスナックバーを閉じれるように設定しています。
Snackbar
のonClose
オプションを指定して、いると、スナックバー外の要素アクションでも閉じるようです。アニメーションカスタマイズ
スナックバーで
TransitionComponent
を指定しなければGrow
コンポーネントが標準で用意されているようです。
上のコードではSlide
コンポーネントを使って横から入ってくるようにしています。標準のTransitionが動くと、結構モーションが速いので、少しゆっくりめにカスタマイズしてみます。
transitonDuration
プロパティこちらのプロパティで
enter
とexit
指定で入ってくるモーションと、出ていくモーションの指定が行えます。transitionDuration={{ enter: 800, exit: 800, }}モーション指定を行った後のソースは以下です。
import React from 'react'; import Button from '@material-ui/core/Button'; import Snackbar from '@material-ui/core/Snackbar'; import Slide from '@material-ui/core/Slide'; import ClearIcon from '@material-ui/icons/Clear'; // FIXME:せっかくTransitionPropsプロパティあるのでそちらでdirection設定したい... function Transition(props) { return <Slide {...props} direction="left" />; } export default function App() { const [open, setOpen] = React.useState(false); const handleOpen = () => { setOpen(true); }; const handleClose = () => { setOpen(false) }; return ( <div className="App"> <Button variant="contained" onClick={handleOpen}>Register</Button> <Snackbar open={open} message="Complete!" onClose={handleClose} TransitionComponent={Transition} transitionDuration={{ enter: 800, exit: 800, }} action={<ClearIcon onClick={handleClose}/>} /> </div> ); }アニメーションの変更ができました!
さいごに
Material-UIを使うと手軽に様々なモーション、インタラクションの活用ができてすごく便利ですが、そこに縛られてしまうこともあります。
この辺りの細かいオプションが用意されていればすごく利便性上がりますが、ここに苦しめられることも多くあります。同じようなコンポーネントでも用途が違うコンポーネントとして用意されているものも多くあります。
皆さんはReact開発ではどんなコンポーネント開発行ってますか?是非聞かせて欲しい。。2020/3/15 CodeSandbox リンク追加しました!