- 投稿日:2020-02-19T19:17:07+09:00
Reactアプリのデバッグ方法
この記事の目的
Reactの公式ページを見たがReact DevToolsを用いたデバッグ方法についての記述が無かったため(パフォーマンス最適化の項でDevToolsの紹介はあった)、Reactアプリのデバッグを行う上で最低限知っておくべき内容を整理しておく。
参考資料
Reactアプリのデバッグ方法
準備
Reactアプリのデバッグはブラウザで行う。FirefoxとChromeのどちらでもデバッグ用の拡張機能(React Developer Tools)が用意されているので、普段Webアプリのデバッグで利用しているブラウザ向けのDevToolsをインストールして利用する。
ChromeのReact Developer Tools
FirefoxのReact Developer Tools※IE用は存在しないので、IEでのデバッグは諦めてください。。。
React DevToolsの使い方概要
この資料ではChromeのDevToolsで説明する。(FirefoxのDevToolsでも基本同じはず)
アイコンの見方
ChromeのReact DevToolsをインストールすると、ブラウザの右上にReactのアイコンが表示される。
アイコンの色によって意味が異なり、以下の3種類が存在する。
アイコンの種類 Reactで描画されたページか否か ×(Reactで描画されたページではない) ○(Reactで描画されたページ) ○(Reactで描画されたページ) Reactのビルドモード - Production Build Development Build React DevToolsによるデバッグ - 不可 可能 自分が作成したReactアプリをnpm startで起動してWebページを開いた場合、一番右の赤色アイコンが表示される。
画面のコンポーネント構成を見る方法
「Chromeのメニュー」→「その他ツール」→「デベロッパーツール」を開く。
デベロッパーツールのタブメニューから「Components」を選択。
現在ブラウザで表示しているページのコンポーネント構成を確認できる。
また、対象のコンポーネントをクリックすればpropsやstateの値を確認することも可能。
多重階層になっていてお目当てのコンポーネントを探すのが大変なときは、Componentsタブ内の左上にある矢印ボタンを押して画面から対象コンポーネントを選択することも可能。
(ネストされたコンポーネントを正確にポインティングするのは難しいようなので、補助的に使ってあげてください)ブレイクポイントを設定してステップ実行でデバッグする
React Developer ToolsでComponentsタブを開き、ブレイクポイントを設定したいコンポーネントを選択した状態で「<>」アイコンをクリックする。
コンポーネントのソースがReact Developer Toolsに表示されるので、ブレイクポイントを設定したい行番号をクリックする。ブレイクポイントを設定した行番号は緑色になる。
ブレイクポイントを設定した状態でWebブラウザ内でReactアプリを操作すると、ブレイクポイントで処理が止まる。ブレイクポイントで処理が止まると、対象の行が緑色で網掛けされる。
ブレイクポイントで処理が停止したら、以下のいずれかの実行が可能。
- Resumu script execution
- ブレイクポイントからそのまま処理が続行される
- Step over next function call
- ステップオーバーで実行
- 今いる関数内の処理はすべて実行し、次の関数が呼ばれたタイミングで処理をブレイク(停止)する
- Step into next function call
- ステップインで実行
- 今いる関数から別の関数が呼ばれるタイミングまで処理を進め、別の関数に入ったタイミングで処理をブレイク(停止)する
- Step out of current function
- ステップアウトで実行
- 今いる関数内の処理はすべて実行し、今いる関数の呼び出し元に戻ったタイミングで処理をブレイク(停止)する
- Step
- 一行づつ順番に実行する
- 投稿日:2020-02-19T18:40:05+09:00
React Routerのざっくり概要
この記事の目的
公式ページのガイドを見てもらうのが一番だが、公式は英語の情報しかないためReact Routerを使用するにあたって押さえておきたいポイントをかいつまんで説明する。
参考資料
React Routerのざっくり概要
React Routerとは
ReactでSPA(Single Page Application)を実現し、SPAのルーティングを管理するためのモジュール。
Reactのルーティングライブラリは過去にいくつか出ては消えてを繰り返してきたが、現在はReact Routerがデファクトスタンダードと言える。基本的な使い方
画面の構成例
Material UIのテンプレートページで紹介されている、以下の画面構成を例にReact Routerの使い方を説明する。
画面の構成例をコンポーネント単位に分解
上記の画面は、コンポーネント単位に分解すると以下のような構成となる。
左端のDrawerコンポーネントにメニューがあり、メニューを選択するとmainタグの領域にコンテンツを表示する。
このとき、ページ遷移(HTMLのhttpリクエスト・レスポンス)は発生せず、DrawerコンポーネントとAppBarコンポーネントの表示はそのままにmain領域のコンテンツだけを入れ替える動作となる。ページ遷移(HTMLのhttpリクエスト・レスポンス)を行わないでコンテンツの入れ替えを行うので、SPA(Single Page Application)となっている。
React Routerをコードに仕込む例
上記の画面例をReact Routerで実現する場合のコード例を示す。
コードの例
app.tsx// ※説明に必要なステップ以外は省略している import React from "react"; import Dashboard from "./components/Top"; import About from "./components/About"; import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom"; //ポイント1 const App: React.FC = () => { return ( <Router> //ポイント2 // AppBar <AppBar> </AppBar> // Drawer <Drawer> <List> <ListItem button component={Link} to={/}> //ポイント3a <ListItemText primary="Dashboard" /> </ListItem> </List> <List> <ListItem button component={Link} to={/about}> //ポイント3b <ListItemText primary="About" /> </ListItem> </List> <Drawer> // main <main> <Switch> //ポイント4a <Route exact path="/"> //ポイント4b <Dashboard /> </Route> <Route exact path="/about"> //ポイント4c <About /> </Route> </Switch> <main> </Router> ); }; export default App;注目すべきポイント
ポイントは以下の4点。
react-router-dom
をインポートする- メニュー領域(この例の場合Drawerコンポーネント)とコンテンツ領域(この例の場合はmainタグ)を
<Router>
タグで囲む(Routerコンポーネントの一部として扱われる)- メニュー領域(Drawerコンポーネント)
- メニューから「Dashboard」を選択した場合、
/
にルーティングすることを定義している- メニューから「About」を選択した場合、
/about
にルーティングすることを定義している- コンテンツ領域(mainタグ)
- コンテンツを表示する領域を
<Switch>
タグで囲む(Switchコンポーネントの一部として扱われる)<Route>
タグでルーティングを定義する。この場合、/
にルーティングしたらmainタグの領域にDashboardコンポーネントを表示するように定義している<Route>
タグでルーティングを定義する。この場合、/about
にルーティングしたらmainタグの領域にAboutコンポーネントを表示するように定義している応用的な使い方
イベント起因でルーティング
基本的な使い方では、Linkコンポーネントを使ってボタンを押したらルーティングする方法を取ったが、ルーティングHistoryに直接パスを追加するとこでonClickイベントなどのイベント起因でルーティングすることも可能。
コードの例
order.tsx// ※説明に必要のないステップは省略している import React from "react"; import { withRouter } from 'react-router'; //ポイント1 class Orders extends React.Component { routingToAbout = () => { this.props.history.push('/about') //ポイント3 } render() { return ( <div> <Button onClick={this.routingToAbout}> //ポイント2 aboutへ移動 </Button> </div> ) } } export default withRouter(Orders)注目すべきポイント
ポイントは以下の3点。
- インベント起因のルーティングではwithRouterコンポーネントを使用するので、
'react-router'
をインポートする- onClickイベントでルーティングしたいので、onClickイベントが発火したらコンポーネント内の関数を呼ぶように設定する
- onClickイベントから呼ばれた関数内では、
this.props.history.push('/about')
でルーティングHistoryにaboutページへのルーティングを追加する。これによって、ルーティングHistoryの最後がaboutページになるので、aboutページに遷移することになる
- 投稿日:2020-02-19T16:37:00+09:00
create-react-appが公式にreduxテンプレートを公開した件
Reactを触ったことがあるみなさんならご存知のcreate-react-appですが、公式にReduxのテンプレートを公開したようです
I'm excited to announce that:
— Mark Erikson (@acemarke) 2020年2月18日
??The official Redux template for Create-React-App is now available! ??
To use it:
npx create-react-app my-app --template redux
Thanks to @BenLorantfy for putting the template together!
Release notes:https://t.co/gdRbgZGAPS使い方は簡単
npx create-react-app {app_name} --template redux
templateにreduxをしてあげるだけで使えちゃいます通常のcreate-react-appとの差分
普通の
create-react-app
コマンドで作成したときと何が違うのか一部抜粋してみましたまずは起動してみると...
カウンターアプリのサンプルが表示されていますね
package.json
通常のcreate-react-appから追加でインストールされているモジュールは
- @reduxjs/toolkit
- react-redux
の2つでした
ディレクトリ構造
src
以下のディレクトリ構造は以下のようになっていますsrc ├── App.css ├── App.js ├── App.test.js ├── features │ └── counter │ ├── Counter.js │ ├── Counter.module.css │ └── counterSlice.js ├── index.css ├── index.js ├── logo.svg ├── serviceWorker.js ├── setupTests.js └── store.js大きな違いとしては、カウンターのサンプルが
features
以下に作成されていますまた、
store
が始めから作成してあり、index.js
のProvider
に既に登録されていますsrc/index.jsReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );カウンターアプリも含め基本的に全て
Hooks
とFunctional Component
で書かれていましたtypescript対応
現在はまだ公式から
typescript
に対応したものは公開してないようです
でも近いうちに公開されるはず...補足ですが、
npx create-react-app {app_name} --typescript
は廃止予定らしいので
npx create-react-app {app_name} --template typescript
を利用しましょうリンク
github release note
https://github.com/reduxjs/cra-template-redux/releases/tag/v1.0.0
- 投稿日:2020-02-19T15:05:45+09:00
Next.js で node-sass の代わりに dart-sass を使う
はじめに
Node.js のバージョンの違いとかでエラーを吐いちゃう node-sass に疲れたので、dart-sass を Next.js で使う方法を書いていきます。node-sass と dart-sass の違いについては本記事では触れません。
環境
- Next.js 9.2.2
- Node.js 12.16.0
インストール
npm i -D @zeit/next-sass sass fibers上記の sass が dart-sass になります。また fibers と組み合わせることでパフォーマンスの改善になるみたいなので入れておきましょう。詳しくは GitHub: sass/dart-sass で。
@zeit/next-sass と sass-loader で node-sass が入ってないよって警告が出るかとは思いますが、とりあえず素直に受け入れて、今は無視しておきましょう。
設定
next.config.jsconst withSass = require("@zeit/next-sass"); module.exports = withSass({ cssModules: true, sassLoaderOptions: { implementation: require('sass'), sassOptions: { fiber: require('fibers') } } }); module.exports = { experimental: { scss: true } };experimental 部分は Next.js 9.2 で導入された Built-In CSS Module Support for Component-Level Styles を scss で書けるようにするための記述なので、無視してかまいません。
まとめ
特に node-sass で問題ないのなら dart-sass に乗り換える必要もないのかなとは思いますが、疲れを感じたら dart-sass という選択もアリかなと、導入して思いました。
リンク
- 投稿日:2020-02-19T09:27:00+09:00
【React】TypeError: Cannot read property '***' of undefined の対処法
今回は練習のためにreactでTodoリストを作成していた時にハマったエラーと対処法をメモしときたいと思います。
TypeError: Cannot read property '***' of undefined
これはリストの削除機能を作る時にハマりました。
そのまま翻訳すると「未定義のプロパティ「***」を読み取れません」といった感じなんですが、これはちゃんと定義されていないことが問題なようなのでアロー関数で書いてあげれば治りました。
test.jsremoveTask(text){ var updatedTasks = this.state.tasks; updatedTasks.splice(updatedTasks.indexOf(text), 1); this.setState({tasks: updatedTasks}); }これを以下に変更。
test.jsremoveTask=(text)=>{ var updatedTasks = this.state.tasks; updatedTasks.splice(updatedTasks.indexOf(text), 1); this.setState({tasks: updatedTasks}); }こんな感じでちゃんと渡してあげたらスッと治りました。
Cannot read property 'map' of undefined
このエラーはほとんど普通にタイプミスです。
私の場合は「var tasksList=[];」を「tasks=tasksList」に定義し直していたのを忘れて「tasksList」で進めてしまっていたのでエラーが出たといった感じでした。まとめ
どちらもしょうもないミスなんですが、結構ハマった時間が長かったのでもし困っている方の助けになれたら嬉しいです。