20210501のReactに関する記事は4件です。

[簡単]モダン構成なSPAで作るチュートリアル②(ルーティング編)

SPAで作るタスク管理アプリのチュートリアル - ルーティング編 今回は第②弾でReact側ルーティングを設定する部分をやっていくで ①環境構築(Docker/Laravel/React.js/Material-UI) ②React側でルーティング設定 ③Reactで一覧テーブル作成 ④seederで作ったDBのデータをReactに渡して一覧に表示 ⑤新規登録機能 ⑥編集・削除機能 react-router-domとは react-router-domってなんやねんって話なんやけど、簡単に言うとURLのPathに対してReact側で表示するコンポーネントを切り替えることができるで。 使い方とか詳しいことに関しては、まぁググってや。 こんなんできるようになるで ボタンクリックするとページ切り替えできるような機能をこれから作っていくな。 npmでreact-router-domを導入 make npm-install react-router-domを実行 $ make npm-install react-router-dom docker-compose exec web npm install ---------下記のようなメッセージ出たらOK + react-router-dom@5.2.0 added 10 packages from 5 contributors and audited 1241 packages in 11.827s 100 packages are looking for funding run `npm fund` for details found 0 vulnerabilities こんな感じでpackage-jsonが更新されるはずやわ package.json "dependencies": { "@material-ui/core": "^4.11.4", "react-router-dom": "^5.2.0" } ルーティング設定のため/js以下のディレクトリ構成を変更する やることは - /components下のExample.jsを新規ディレクトリpages下に移動 - /js直下に新規ファイルroute.jsを作成 実行後のディレクトリ構成はこんな感じ VSCODE使っててExapme.jsの移動のときに、「import先のディレクトリを変えますか」的なメッセージが出たら「はい」を押す ┗ js ┗ components (Example.jsを空になる) ┗ pages (新規ディレクトリ) ┗ Example.js (/componentsから移動) ┗ app.js ┗ bootstrap.js ┗ route.js (新規作成ファイルで中身はまだ空のままでOK) /js直下のapp.jsがエディタが良しなにやってくれていることを確認する (変更されていない場合は自分で変更を加える) app.js // 15行目 - require('./components/Example'); + require('./pages/Example'); pages下のExample.jsが表示できることを確認 Example.js <div className="card-header">React導入できたわな??</div>   //13行目辺り - <div className="card-body">Im an example component!</div> + <div className="card-body">pages下に移動出来た??</div> <Button color="secondary" variant="contained">ワイがMaterial-UIのボタンやな??</Button> ビルドする $ make npm-dev localhostにアクセスし表示できることを確認 「pages下に移動出来た??」が表示できていればOK 変更差分は下記のようになるはずや コミットしておこう $ git add . $ git commit -m "react-router-dom導入しディレクトリ変更" react-router-domを利用してページを表示してみる laravelでphp artisan ui react --authによってReactを導入した場合、 /js/app.jsが読み込まれる様になっているな。 先程requireの部分を './components/Example' → './pages/Example'に変えたことによって pages下のExample.jsが表示されたことからも分かるように、 app.jsの中のrequire()の中で呼ばれたjsファイルが一番最初に呼ばれるんやな。 React側でルーティングしたいので最初に呼ばれるファイルを /js/route.js/ /js/app.jsを変更する app.js // 15行目 - require('./pages/Example'); + require('./route'); route.jsに下記を貼り付ける import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter, Route, Switch, } from 'react-router-dom'; import Example from './pages/Example'; function App() { return ( <div> <Switch> //ここに、pathと対応するコンポーネントを書いていく </Switch> </div> ); } ReactDOM.render(( <BrowserRouter> <App /> </BrowserRouter> ), document.getElementById('app')) 使っているタグがどんな意味か知りたかったらreact-router-domをimportしてるから、ドキュメント読もうな。 公式ドキュメント の中にルーティングの設定を書いていくで //route.jsに下記を追記 <Switch> <Route path='/example' exact component={Example} /> </Switch> これはpathが/exampleだったらExampleコンポーネントを表示するっているルーティングの設定やね。 変更箇所がわかるようにボタンの文字を変更し不要な記述を削除する Example.js <div className="card-header">React導入できたわな??</div> <div className="card-body">pages下に移動出来た??</div> //14行目のボタンを「Homeに遷移ボタン」に変更する - <Button color="secondary" variant="contained">ワイがMaterial-UIのボタンやな??</Button> + <Button color="secondary" variant="contained">Homeに遷移ボタン</Button> </div> </div> </div> @@ -20,7 +20,3 @@ function Example() { } export default Example; 下記の表示設定はroute.js側で行えるようになったため、削除 //if (document.getElementById('app')) { // ReactDOM.render(<Example />, document.getElementById('app')); //} ビルドする $ make npm-dev 先程同様にlocalhostにアクセスしたら、返す対象がないため、jsエラーが出るはず。 localhost/exampleにアクセスすると下記が表示されるはず ボタンが変わっていればOKな!!!! コミットしとくで $ git add . $ git commit -m "routerを経由してページを表示" もう一つページ(Home.js)を用意してボタンで遷移できるようにしてみる /pagesディレクトリにはExacple.jsとHome.jsが存在する状況になるで ファイル作れたら進んでな。 /pages/Home.jsを用意し下記の様に設定する Home.js import React from 'react'; import ReactDOM from 'react-dom'; import { Button, Card } from '@material-ui/core'; function Home() { return ( <div className="container"> <Card> <Button color="primary" variant="contained" href={`/example`}>Exampleに遷移</Button> </Card> </div> ); } export default Home; ボタンが一つあるだけの画面のコンポーネントやな。 表示するにはルーティングの設定がいるな。 Home.jsのルーティングを記載する route.js // 8行目 以降 import Example from './pages/Example'; // Exampleの下にHome.jsをインポートする import Home from './pages/Home'; function App() { return ( <div> <Switch> <Route path='/example' exact component={Example} /> // Homeコンポーネントを表示するための設定を記述 <Route path='/' exact component={Home} /> </Switch> </div> ); } コンポーネントのimportとルーティングの設定を書いただけやな。 exactってなんやねんって気になってる人いてるかもしれへんけど、 これ書いてなかったら前方一致で判定されるはずやから基本は書いといたほうがえと思うわ。 ビルドする $ make npm-dev ビルドできたらlocalhostにアクセスして下記のように表示されたらOKや 表示されているボタンにhrefに/exampleを設定したのでクリックすると expampleページに遷移できるはずやで Exampleコンポーネントのボタンにもhrefを設定する Example.js //14行目にhrefを追加 <Button color="secondary" variant="contained" href={`/`}>Homeに遷移ボタン</Button> これで互いのページを行き来できるようになったはずやで ビルド $ make npm-dev ビルドできたら互いのページ行き来してみて遊んでみたや つかめてきたら新しいページを用意してroute.jsにルーティングの設定を記述したら 理解深まると思うわ コミットしとこうな $ git add . $ git commit -m "Homeコンポーネントを作成しrouteingの設定" 纏め このようにlaravel側では環境構築編で設定したように、どのパスが指定されたとしてもapp.blade.phpを表示するように設定しておいてReact.js側でルーティングの設定をすることが出来たな。 ここまで出来たらReactやったことある人ならどんどんページ作っていくことはできそうやな。 ただデータのやり取りが出来てないからそれは次回以降の記事に書いていくことにするで 次はReactで一覧テーブルのコンポーネント作っていくところをやっていこうと思うで。 次回はReactで一覧表示 ほなここまで出来た人はLGTMしといてな。 ソースはGitHubに乗せておくから分からんときはコミット履歴見たら解決できるかもな。 https://github.com/morry48/LaravelReactTaskApp
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【React】Materialu-uiでGoogle関連のアイコンを表示する方法

皆さんこんにちは! ふと、Materialu-uiのアイコンで「Google」のアイコンを表示させたかったのですが、なぜかMaterialu-uiには存在しませんでした。 YoutubeアイコンはあるのになぜGoogleアイコンは無いんでしょうね。。。 そんな問題に直面していたのですが、解決することができました。 npmの@trejgun/material-ui-icons-googleというパッケージです。 これを使えばGoogle関連のほとんどのアイコンを使用することができます。 こんな感じで。 一応URLも載せておきますね。 https://www.npmjs.com/package/@trejgun/material-ui-icons-google こちらのサイトにもやり方は書いているのですが、せっかく見て頂いた方々にこちらを見て下さいなんて言えない。 ということで説明していきます! パッケージのインストール まずはパッケージのインストールを行います。 npm i --save @trejgun/material-ui-icons-google コンポーネントとして使用 あとはいつも通りコンポーネントとして使用します。 import { Search } from "@trejgun/material-ui-icons-google" <Button startIcon={<Search />}>Google アカウントでログイン</Button> こんな感じでMaterialu-uiでGoogle関連のアイコンを使用することができます! 以上、「【React】Materialu-uiでGoogle関連のアイコンを表示する方法」でした!! Thank you for reading
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React Hooks と TypeScript で簡単 TODO アプリ

フロントエンド強化月間投稿記事 はじめに 公式のチュートリアル以外のチュートリアルを探している人向けです。 完成予想図 See the Pen TODO App by React & TypeScript by sprout2000 (@sprout2000_jp) on CodePen. 下準備 create-react-app で TypeScript 用のひな形を準備する。 bash $ npx create-react-app todo --template typescript Need to install the following packages: create-react-app Ok to proceed? (y) Creating a new React app in C:\Users\qiita\Downloads\todo. Installing packages. This might take a couple of minutes. Installing react, react-dom, and react-scripts with cra-template-typescript... ~ snip ~ We suggest that you begin by typing: cd todo npm start Happy hacking! $ cd todo 手順 簡潔すぎるかもしれない手順とスクリーンショット。 1. 初期状態 Hello. とのみ表示される関数コンポーネント。 src/index.tsx import React from 'react'; import ReactDOM from 'react-dom'; const App: React.VFC = () => { return ( <div> <h1>Hello.</h1> </div> ); }; ReactDOM.render(<App />, document.getElementById('root')); create-react-app が自動的にホットリロードしてくれないとき(まれによくある)は、ブラウザのリロードボタンや Ctrl+R を使う。 2. Todo を入力するフォームを作成 onSubmit や onChange のイベントは preventDefault() してしまっているので特に何も起きない index.tsx const App: React.VFC = () => { return ( <div> <form onSubmit={(e) => e.preventDefault()}> <input type="text" value={''} onChange={(e) => e.preventDefault()} /> <input type="submit" value="追加" onSubmit={(e) => e.preventDefault()} /> </form> </div> ); }; 3. フォームに入力された文字列を状態 (=state)として保持する useState フック は現在の state の値と、それを更新するための関数とをペアにした配列を返す useState の引数はそのステートの初期値 src/index.tsx - import React from 'react'; + import React, { useState } from 'react'; import ReactDOM from 'react-dom'; const App: React.VFC = () => { + const [text, setText] = useState(''); + return ( <div> <form onSubmit={(e) => e.preventDefault()}> - <input type="text" value={''} onChange={(e) => e.preventDefault()} /> + <input + type="text" + value={text} + onChange={(e) => setText(e.target.value)} + /> <input type="submit" value="追加" onSubmit={(e) => e.preventDefault()} /> </form> </div> ); }; 4. Todo の仕様を考える(その1) タスクの内容として string 型の value というプロパティを持つ。 index.tsx interface Todo { value: string; } const App: React.VFC = () => { タスクたち(todos 複数)は Todo 型オブジェクトの配列 とする。 index.tsx const App: React.VFC = () => { const [text, setText] = useState(''); + const [todos, setTodos] = useState<Todo[]>([]); return ( 5. onSubmit() イベントで text ステート の内容を todos ステート配列に追加する 配列のステートをそのまま触ってはいけない コピーに対して変更を加えてから更新すること チュートリアル:React の導入 - イミュータビリティは何故重要なのか(公式) 6. todos ステートを更新するコールバック関数を作成する いったん e.preventDefault() しているのは Enter キー打鍵でページそのものがリロードされてしまうのを防ぐため。 src/index.tsx const [todos, setTodos] = useState<Todo[]>([]); // todos ステートを更新する関数 const handleOnSubmit = ( e: React.FormEvent<HTMLFormElement | HTMLInputElement> ) => { e.preventDefault(); // 何も入力されていなかったらリターン if (!text) return; // 新しい Todo を作成 const newTodo: Todo = { value: text, }; /** * スプレッド構文を用いて todos ステートのコピーへ newTodo を追加する * * 以下と同義 * const oldTodos = todos.slice(); * setTodos(oldTodos.splice(0, 0, newTodo)); * **/ setTodos([newTodo, ...todos]); // フォームへの入力をクリアする setText(''); }; イベントの型がわからない時は、VSCode であればイベント上でマウスカーソルを hover させるとポップアップが表示される。 7. コールバック関数をイベントに割り当てる コールバックとして渡すのは関数そのもの () => hoge() hoge() のみだと即時に実行されてしまうので用をなさない src/index.tsx return ( <div> - <form onSubmit={(e) => e.preventDefault()}> + <form onSubmit={(e) => handleOnSubmit(e)}> <input type="text" value={text} onChange={(e) => setText(e.target.value)} /> - <input type="submit" value="追加" onSubmit={(e) => e.preventDefault()} /> + <input type="submit" value="追加" onSubmit={(e) => handleOnSubmit(e)} /> </form> </div> フォームへ入力して submit すると ステート (todos) が更新されていることが確認できる。 8. ステート todos を展開してページに表示する todos (=配列) を非破壊メソッドである Array.prototype.map() を使って <li></li> タグへ展開する。 src/index.tsx <div> <form onSubmit={(e) => handleOnSubmit(e)}> <input type="text" value={text} onChange={(e) => setText(e.target.value)} /> <button onClick={() => handleOnClick()}>追加</button> </form> <ul> {todos.map((todo) => { return <li>{todo.value}</li>; })} </ul> </div> これだけでは各 <li> に key が設定されていないため、以下のような警告が表示されてしまう。 チュートリアル:React の導入 - key を選ぶ(公式) 9. Todo の仕様を考える(その2) それぞれの Todo (タスク)に一意な ID を与える必要があるため、number 型のプロパティを Todo 型に追加する。 src/index.tsx interface Todo { value: string; id: number; } handleOnSubmit() メソッドを更新。 src/index.tsx const handleOnSubmit = ( e: React.FormEvent<HTMLFormElement> | React.FormEvent<HTMLInputElement> ) => { e.preventDefault(); if (!text) return; const newTodo: Todo = { value: text, + id: new Date().getTime(), }; setTodos([newTodo, ...todos]); setText(''); }; <li></li> タグに key (=id) を付加する。 src/index.tsx <ul> {todos.map((todo) => { return <li key={todo.id}>{todo.value}</li>; })} </ul> 10. 登録済みの todo を編集可能にする todo.value を <input /> タグでラップする。 src/index.tsx <ul> {todos.map((todo) => { return ( <li key={todo.id}> <input type="text" value={todo.value} onChange={(e) => e.preventDefault()} /> </li> ); })} </ul> ここでも、とりあえず e.preventDefault() しているので入力しても何も起きない。 11. 登録済み todo が編集された時のコールバック関数を作成 どの todo が編集されたのか特定するため、その todo の id を引数として受け取る e.target.value を書き換え後の todo.value の値とするために第2引数として受け取る src/index.tsx const handleOnEdit = (id: number, value: string) => { /** * 引数として渡された todo の id が一致する * todos ステート(のコピー)内の todo の * value プロパティを引数 value に書き換える */ const newTodos = todos.map((todo) => { if (todo.id === id) { todo.value = value; } return todo; }); // todos ステートを更新 setTodos(newTodos); }; 上のコールバック関数を <input onChange={} /> に割り当てる。 src/index.tsx <ul> {todos.map((todo) => { return ( <li key={todo.id}> <input type="text" value={todo.value} - onChange={(e) => e.preventDefault()} + onChange={(e) => handleOnEdit(todo.id, e.target.value)} /> </li> ); })} </ul> 12. タスクの完了/未完了を操作できるようにする - Todo の仕様を考える(その3) Todo 型に完了/未完了を示すプロパティを追加する 完了/未完了 (= yes or no) を表すので型は Boolean 型 src/index.tsx interface Todo { value: string; id: number; + checked: boolean; } handleOnSubmit() メソッドを更新する。 src/index.tsx if (!text) return; const newTodo: Todo = { value: text, id: new Date().getTime(), + checked: false, }; setTodos([newTodo, ...todos]); それぞれの todo の前へチェックボックスを置く。 index.tsx <ul> {todos.map((todo) => { return ( <li key={todo.id}> <input type="checkbox" checked={todo.checked} onChange={(e) => e.preventDefault()} /> <input type="text" value={todo.value} onChange={(e) => handleOnEdit(todo.id, e.target.value)} /> </li> ); })} </ul> 13. チェックボックスがチェックされたときのコールバック関数を作成する 上の handleOnEdit() とパターンは同じ。 src/index.tsx const handleOnCheck = (id: number, checked: boolean) => { const newTodos = todos.map((todo) => { if (todo.id === id) { todo.checked = !checked; } return todo; }); setTodos(newTodos); }; チェックボックスのイベントへ紐付ける。 src/index.tsx return ( <li key={todo.id}> <input type="checkbox" checked={todo.checked} onChange={() => handleOnCheck(todo.id, todo.checked)} /> <input type="text" value={todo.value} onChange={(e) => handleOnEdit(todo.id, e.target.value)} /> </li> ); このままではチェック済みのタスクも編集できてしまうので、チェック済みの項目は入力フォームを無効化する。 src/index.tsx <input type="text" + disabled={todo.checked} value={todo.value} onChange={(e) => handleOnEdit(todo.id, e.target.value)} /> 14. 登録済みの todo を削除可能にする 入力フォームの後ろへ削除ボタンを追加する。 index.tsx return ( <li key={todo.id}> <input type="checkbox" checked={todo.checked} onChange={() => handleOnCheck(todo.id, todo.checked)} /> <input type="text" disabled={todo.checked} value={todo.value} onChange={(e) => handleOnEdit(todo.id, e.target.value)} /> <button onClick={() => console.log('removed!')}>削除</button> </li> ); 15. Todo の仕様を考える(その4) checked の場合と同様に removed というフラグを追加する。 src/index.tsx interface Todo { value: string; id: number; checked: boolean; removed: boolean; } handleOnSubmit() メソッドを更新する。 src/index.tsx if (!text) return; const newTodo: Todo = { value: text, id: new Date().getTime(), checked: false, removed: false, }; setTodos([newTodo, ...todos]); 16. 削除ボタンがクリックされたときのコールバック関数を作成する これも handleOnEdit() や handleOnChecked() と同じパターン。 src/index.tsx const handleOnRemove = (id: number, removed: boolean) => { const newTodos = todos.map((todo) => { if (todo.id === id) { todo.removed = !removed; } return todo; }); setTodos(newTodos); }; todo.removed のフラグによってボタンのラベルを入れ替える。 src/index.tsx <button onClick={() => handleOnRemove(todo.id, todo.removed)}> {todo.removed ? '復元' : '削除'} </button> 削除されたアイテムのチェックボックスと入力フォームも無効化する。 src/index.tsx <input type="checkbox" disabled={todo.removed} checked={todo.checked} onChange={() => handleOnCheck(todo.id, todo.checked)} /> <input type="text" disabled={todo.checked || todo.removed} value={todo.value} onChange={(e) => handleOnEdit(todo.id, e.target.value)} /> 17. タスクをフィルタリングする機能を追加する このままでは削除済みのアイテムもそのまま表示されてしまうので、タスクをフィルタリングする機能を追加する。 フィルタリングするセレクタを作成 ここでも onChange はとりあえずダミー。 src/index.tsx <div> <select defaultValue="all" onChange={(e) => e.preventDefault()}> <option value="all">すべてのタスク</option> <option value="checked">完了したタスク</option> <option value="unchecked">未完了のタスク</option> <option value="removed">削除済みのタスク</option> </select> <form onSubmit={(e) => handleOnSubmit(e)}> ~ snip ~ </div> 18. 現在のフィルターを格納する filter ステートを追加する filter は4種類とする。 src/index.tsx type Filter = 'all' | 'checked' | 'unchecked' | 'removed'; 前項の <option /> タグの値を Filter 型のステート として保持する。 src/index.tsx const App: React.VFC = () => { const [text, setText] = useState(''); const [todos, setTodos] = useState<Todo[]>([]); + const [filter, setFilter] = useState<Filter>('all'); 19. セレクタの onChange イベントで filter ステートを更新する Filter を単なる string 型 にすれば下のようなキャストは不要だが、次項の switch 文で型によるエディタの補完を享受するため、あえて Filter 型 を利用する。 src/index.tsx <select defaultValue="all" - onChange={(e) => e.preventDefault()}> + onChange={(e) => setFilter(e.target.value as Filter)}> <option value="all">すべてのタスク</option> <option value="checked">完了したタスク</option> <option value="unchecked">未完了のタスク</option> <option value="removed">削除済みのタスク</option> </select> 20. フィルタリング後の Todo 型の配列を返す関数を用意する <ul></ul> タグの中で展開されている todos ステート をタグへ渡す前に加工する 現在の filter ステート に応じて Todo 型配列 の要素をフィルタリングする Array.prototype.filter() メソッドも非破壊メソッド src/index.tsx const filteredTodos = todos.filter((todo) => { switch (filter) { case 'all': return !todo.removed; case 'checked': return todo.checked && !todo.removed; case 'unchecked': return !todo.checked && !todo.removed; case 'removed': return todo.removed; default: return todo; } }); 21. todos ステートを展開する <ul></ul> タグにフィルタリング済みのリストを渡す src/index.tsx <ul> - {todos.map((todo) => { + {filteredTodos.map((todo) => { return ( <li key={todo.id}> <input type="checkbox" disabled={todo.removed} 「削除済みのタスク」や「完了済みのタスク」が表示されている時は、入力フォームは無効化する。 src/index.tsx <form onSubmit={(e) => handleOnSubmit(e)}> <input type="text" value={text} + disabled={filter === 'checked' || filter === 'removed'} onChange={(e) => setText(e.target.value)} /> <input type="submit" + disabled={filter === 'removed' || filter === 'checked'} value="追加" onSubmit={(e) => handleOnSubmit(e)} /> </form> 22. 「ゴミ箱を空にする」ボタンを作成する フィルターで「削除済み」の Todo リストを表示しているときには、削除済みタスクを完全に消去できるようにする。 フィルターが「削除済み」の場合は「ゴミ箱を空にする」するボタンを表示し、それ以外のときは従前の入力フォームを表示する。 src/index.tsx <option value="removed">削除済みのタスク</option> </select> {filter === 'removed' ? ( <button onClick={() => console.log('remove all')}> ゴミ箱を空にする </button> ) : ( <form onSubmit={(e) => handleOnSubmit(e)}> <input type="text" value={text} disabled={filter === 'checked' || filter === 'removed'} onChange={(e) => setText(e.target.value)} /> <input type="submit" value="追加" disabled={filter === 'checked' || filter === 'removed'} onSubmit={(e) => handleOnSubmit(e)} /> </form> )} <ul> {filteredTodos.map((todo) => { こうなると入力フォームが描画される場合には filter === 'removed' という状態が発生し得ないので、入力フォームからこれらを削除する。 src/index.tsx {filter === 'removed' ? ( <button onClick={() => console.log('remove all')}> ゴミ箱を空にする </button> ) : ( <form onSubmit={(e) => handleOnSubmit(e)}> <input type="text" value={text} disabled={filter === 'checked'} onChange={(e) => setText(e.target.value)} /> <input type="submit" value="追加" disabled={filter === 'checked'} onSubmit={(e) => handleOnSubmit(e)} /> </form> )} 23. 「ゴミ箱を空にする」コールバック関数を作成する todos ステート配列から removed フラグが立っている要素を取り除くのみなので、これまでと同様のパターンで処理すればいい。 src/index.tsx const handleOnEmpty = () => { const newTodos = todos.filter((todo) => !todo.removed); setTodos(newTodos); } src/index.tsx {filter === 'removed' ? ( + <button onClick={() => handleOnEmpty()}>ゴミ箱を空にする</button> ) : ( <form onSubmit={(e) => handleOnSubmit(e)}> <input type="text" value={text} disabled={filter === 'checked'} onChange={(e) => setText(e.target.value)} /> <input type="submit" value="追加" disabled={filter === 'checked'} onSubmit={(e) => handleOnSubmit(e)} /> </form> )} ゴミ箱が空の場合(= removed フラグが立っているタスクが todos ステート配列に存在しない)には、ボタンを無効化する。 src/index.tsx <button onClick={() => handleOnEmpty()} disabled={todos.filter((todo) => todo.removed).length === 0} > ゴミ箱を空にする </button> さらなる改良のヒント CSS フレームワークなどを利用してルック&フィールを洗練させよう Web ストレージを利用して Todo リストがリロード後も保持されるようにしよう ドラッグ&ドロップで Todo リストの順番を並び替えられるようにしよう おすすめのドキュメント
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gatsby.jsでreact-reduxを使う方法

皆さんこんにちは! 今回はGatsby.jsでreduxを使用する方法を書いていこうかなと思います。 素のReactと実装方法が少しだけ異なるので、ぜひGatsby.jsでreduxを使いたいという方はご覧ください! それでは説明していきます。 パッケージをインストール まずは必要なパッケージをインストールしてください。 npm install --save redux react-redux redux-thunk gatsby-plugin-react-redux reduxの設定 次に、reduxの設定を行っていきます。 store.js import { applyMiddleware, combineReducers, createStore as reduxCreateStore } from "redux" import thunk from "redux-thunk" import Test from "./test" export default function createStore() { let middleWares = [thunk] return reduxCreateStore( combineReducers({ test: Test }), applyMiddleware(...middleWares) ) } gatsby-configの設定 次は、gatsby-config.jsに以下の設定を加えて下さい。 module.exports = { plugins: [ // 省略 { resolve: `gatsby-plugin-react-redux`, options: { pathToCreateStoreModule: "@/store.js" // 先ほど作成したreduxの設定ファイルのパスを入力 } } ], } Providerの設置 最後にstoreの情報を扱えるようにLayout.jsのような毎回レンダリングされる要素の配下にProviderを設置してあげましょう! Layout.js import React from "react" import { Provider } from "react-redux" import createStore from "@/store.js" // reduxの設定を行ったファイル import { Header } from "../Header" export const store = createStore() const Layout = (props) => { return ( <Provider store={store}> <Header /> <main></main> </Provider> ) } export default Layout propsとしてstoreプロパティにcreateStore()で作成したstoreを渡してあげましょう。 このようにしてstoreの情報を参照することができます! いかがだったでしょうか? こうしてみると案外簡単なものですね。 皆さんもぜひ使って下さい! 以上、「Gatsby.jsでreact-reduxを使う方法」でした! Thank you for reading
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む