Reactアプリケーション開発テクニック を(大体)読んだので注意点をまとめる
正式名称はいまどきのJSプログラマーのための Node.jsとReactアプリケーション開発テクニック。長い。
この本はreactに限らず、electron, react native, flux, webpack, babel, websocket, expressなど、様々な技術を扱っていて、ベストプラクティスを学べるという点ではとても良い。ただ初版が2017年8月と古いのもあって、今の状況とは合わないところもある。第4章以外は読んだので注意点など、気づいたところを書いていく。
私の環境
- Ubuntu 18.04.3 LTS (Bionic Beaver)
- node v10.16.0
- npm 6.10.3
最初に
まず$ webpack
など、コマンドが使えないのはパスが通っていないせい。(npmのバージョンアップのせい?)
使う場合はexport PATH=${PATH}:./node_modules/.bin
でパスを通すか、npx <command>
に置き換えたほうが良い。
パッケージのアップグレード
サンプルコードのパッケージを最新版にしたい場合は
npx npm-check-updates -u
npm install
でアップデートができる。以下は全てパッケージが最新(2019/09/08)の時の話。
最新版reactで本書のコードを実行する場合
react ver16.3以降で
- componentWillMount
- componentWillRecieveProps
- componentWillUpdate
を使うと「廃止予定なので使わないでください」というwarningがでる*1( p146のコードなど)。 詳細は
Update on Async Rendering – React Blog を参照。
componentWillMountはconstructorへ。
「インチとセンチの単位変換コンポーネントを作ろう」(p160)について
inchToCm.jsにはバグがあって、cmChangedが*2.54じゃなくて/2.54(25行目)。
このアプリは上述のnpm-check-updates
でモジュールをアプデするとwebpackが通らないしなんかWARNもでる。
原因としてはbabelのアプデでオプションの指定が変わったことが挙げられる。
webpack.config.jsを
module.exports = { + mode: 'development', - presets: ['es2015', 'react'] + presets: ['@babel/preset-react']
のようにする*2。preset-envはなくてもバンドルが通る。なぜかわからん。npm install @babel/preset-react
でインストールしておく必要がある。WARNはmodule.exports.mode=’development’で消える。
webpackでバンドルすると今度は以下のような、廃止予定のライフサイクルです、というWARNが出る。
Warning: componentWillReceiveProps has been renamed, and is not recommended for use.
対策の詳細は公式を見てもらうのが良いが、この場合ではcomponentWillRecievePropsはgetDerivedStateFromPropsに移動するのが最良*3。
例:
static getDerivedStateFromProps(props, state) { if (props.value !== state.value) { return {value: props.value} } return null }
だがしかしcomponentWillReceiveProps
もgetDerivedStateFromProps
もバグを引き起こしやすいメソッドなので*4できるだけ使わない方法を考えたほうが良いらしい。
初心者なので理解するのに時間がかかったけど、引数の(props, state)は言い換えるなら(nextProps, currentState)で、わざわざcurrentStateを与えてるのはstaticメソッド内ではthisがundefinedになるから。
「汎用的な入力コンポーネントを作ってみよう」(p177)について
何の説明もなくprop-types
モジュールがでてくるが、これはreactが公式にサポートしてる型チェックモジュール。
以下の説明がわかりやすい。
アプリケーションが成長するにつれて、型チェックによって多くの不具合を見つけられるようになります。アプリケーションによっては、Flow もしくは TypeScript のような JavaScript 拡張を使ってアプリケーション全体の型チェックを行うことができるでしょう。しかしそれらを使用せずとも、React は組み込みの型チェック機能を備えています。コンポーネントの props に型チェックを行うために、特別な propTypes プロパティを割当てることができます。
詳細は 公式 を参照。
「DOMに直接アクセスする」(p185)について
ref={obj=> this.hoge = obj}
としてrefを利用するのは16.3から非推奨*5。以下のように編集することでモダンな書き方になる。
headタグ(reactとbabelのアップグレード)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
constructor
this.userNameInput = React.createRef() this.pwInput = React.createRef()
renderメソッド
<input type='text' name='user' ref={this.userNameInput} ...> <input type='password' name='pass' ref={this.pwInput} ...>
createRefは.bind(this)しなくてもOKだった。というかbindしようとするとエラーが出る...なぜ?
「ReactコンポーネントでAjax通信を使う」(p191)について
componentWillMount
を使ってますよというエラーが出る。Ajax通信の場合はcomponentWillMount
じゃなくてcomponentDidMount
メソッドを使おう*6。中身は全く一緒でよい。
p284のコード
fs.renameだとコールバックがなんちゃらとエラーが出るので fs.renameSyncに変えると動く。もしくは以下のようにコールバック関数を書く。
fs.rename(req.file.path, des, (err) => { res.send('ファイルを受信しました<br/>' + `<img src="/pub/${fname}" />`) })
React Routerについて
React Router は今v5だが本書で使ってるv4とは互換性があるらしいので気にする必要はない。
websocket
websocketが急にでてきてわからなくなると思う。基本的な使い方はp324の下の通りだけど、
//「クライアント」がメッセージを受信した時の処理
は//「サーバー」がメッセージを受信した時
の誤植だと思う。多分...。
Wikiシステムを作ってみよう
react router で渡されるthis.props.matchには以下のような値が入ってる。参考までに。
自分のSNSを作ろう(p346)
あんまり関係ないけど、htmlのtitleタグがwikiになってました。
*1:https://ja.reactjs.org/blog/2018/03/27/update-on-async-rendering.html
*2:https://babeljs.io/docs/en/babel-preset-react#usage
*3:https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props
*4:https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#new-lifecycle-getderivedstatefromprops
*5:https://ja.reactjs.org/docs/refs-and-the-dom.html#creating-refs
*6:https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data
HTML5/CSS3モダンコーディングを読んだ
react nativeすげーとか、モダンなwebアプリ作りてえなぁとか、大学のwebシステムのデザイン変えてえなぁとか思ってたのがきっかけだが、とにかくwebデザインの知識がないと始まらないので泣く泣くデザインの本を買った。最初はあんまり興味なかったんだけど、やってくうちに結構楽しくなった。
内容は3つのHPをスクラッチで作っていく形式で、デスクトップデザインの解説が主。レスポンシブ対応は最後の1つしかでてこなかった。レスポンシブの解説がもっとあれば嬉しかったが、まぁ基礎さえ分かればデスクトップデザインもレスポンシブもあまり変わらなそうだとは思う(ほんとか?)。
解説は論理の飛躍なく丁寧で、コラムは細かいけど大切なことが書いてあった。セルフコーディングっていう演習のページがあって、一見難しそうに見えるがヒントもあったし、ちゃんと最後に解答例が載ってたのでちゃんとやりきれる演習だった。総合して良書。大学の教科書聞いてるか〜^^???
ちなみに素のCSSじゃなくて、SCSSを使って勉強してたんだけど、もうバニラCSSに戻る気にはなれない。ネスト使えるのが神。SCSSじゃなくてSASSの方がどう考えても見やすいが、コンパイルできなかったしスタンダードじゃないので諦めた。
次はreactかnode.jsの勉強します。
HTML5/CSS3モダンコーディング フロントエンドエンジニアが教える3つの本格レイアウト スタンダード・グリッド・シングルページレイアウトの作り方
- 作者: 吉田真麻
- 出版社/メーカー: 翔泳社
- 発売日: 2015/11/02
- メディア: Kindle版
- この商品を含むブログを見る
pythonで実験の測定値の確度を求める
def acc(value: str, rdg: float, dgt: int): error = float(value) * rdg / 100 after_dp = value.split('.')[-1] if after_dp: len_after_dp = len(after_dp) lsd = dgt * 10 ** -len_after_dp return round(error + lsd, len_after_dp)
レポート中に苦しみながら書いたやつなのでこれがあってるかどうかは全くわからない。
マイナンバーの交付がやばい
パスワードの扱いがやばい。 まずIDと初期パスワードが紙に印刷されて、封筒に入って送られてくる。え?これ封をする人いるよね?悪意のある人が盗んだらどうなるわけ?
で、次に受付での手続きもやばい。
受付の人「パスワード申請依頼書と、控えの両方にパスワードをご記入ください。」
俺「え?書くんですか?ここに?(俺の字汚いんだが?転記ミスは?パスワード流出は?そもそも依頼書とは????FAXで送ってまた手入力ってこと??ハッシュ化の意味とは??????)」
受付「そうですね〜区役所の方に行ってもらうと自分で設定できるんですが」
俺「わかりました(呆れ)」
もうここで絶対にパスワードお漏らしするのは確信できたのでパスワードジェネレータで捨てパスワード作って書く
受付「ありがとうございますー。こちらの英文字は全て大文字になりますがよろしいですか?」
僕「え?大文字になるんですか?」(組み合わせ数ごっそり減るが????)
受付「そうですねー。この文字はhでよろしいですか?」
僕「○○○○○○です。(もはやどうでも良くなって読み上げる)」
受付「こちらの3種のパスワードは同じでよろしいですね」
僕「はい(怒りを通り越した何か)」
しかもなんとマイナンバーの番号自体がパスワード兼ねてるから漏らしちゃいけないらしい。
django-heroku をインストールするときにエラーがでる(ubuntu)
エラーメッセージが
ERROR: Complete output from command python setup.py egg_info: ERROR: running egg_info creating pip-egg-info/psycopg2.egg-info writing pip-egg-info/psycopg2.egg-info/PKG-INFO writing dependency_links to pip-egg-info/psycopg2.egg-info/dependency_links.txt writing top-level names to pip-egg-info/psycopg2.egg-info/top_level.txt writing manifest file 'pip-egg-info/psycopg2.egg-info/SOURCES.txt' Error: b'You need to install postgresql-server-dev-NN for building a server-side extension or libpq-dev for building a client-side application.\n' ---------------------------------------- ERROR: Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-sqbappkj/psycopg2/
ってなる時は、メッセージの通り、psycog2が依存してる?postgresql-server-dev-NNかlibpq-devをインストールする必要がある。
俺の場合は
sudo apt install libpq-dev
で直った。
こちらも参考
こういうので躓くと大変〜〜〜〜
pythonでリストをn要素の配列に分割する
def divide_list(list_, n): """ divide list into sub-list which have n elements.Reminder is appended to it. Args: list_ (list): list to divide n (int): number of elements which sublist has Returns: list: divided list.It's length is len(list_) // 30 + (1 or 0) Examples: >>> divide_list(list(range(11)), 3) [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]] """ divided_list = [list_[i:i + n] for i in range(0, len(list_), n)] return divided_list
tensorflowでGPUが使われているか確認する
tensorflow-gpuのインストールは
を参照してください。アメリカ語が読めない人は機械学習は無理です諦めてください。
で、正しく使われているか確認したい時は
>>> import tensorflow as tf >>> tf.test.is_gpu_available() True
で確認できる。
参考: https://www.tensorflow.org/api_docs/python/tf/test/is_gpu_available
検索すると
from tensorflow.python.client import device_lib print(device_lib.list_local_devices())
って方法が出てくるけど紹介したヤツのほうが簡単だと思う。
Matebook13でUbuntuとデュアルブートする。
最近Matebook 13を買ったのですが、速攻ubuntu入れたので備忘録として残しておきます。
そもそもデュアルブートじゃなきゃだめなのか?
windows機でubuntu使うとなると、WSLやVirtualBoxなどが候補に上がりますが、正直言ってストレスフルなのでおすすめしません。
LinuxとWindowsをデュアルブートするのは止めたほうが良い | SlackNote
という記事に書かれているように、デュアルブートにはそれなりのリスクがあります。しかし上で挙げた2つともつっかえる点が多く「スムーズに開発するためにubuntuを使いたいのに、そのubuntuが使いにくい」という本末転倒な事態になってしまいます。
WSLを使う場合はGUIアプリケーションの起動が手間ですし、ターミナルもデフォルトのままだとただのコマンドプロンプトなので、自分でカスタムするわけですが、これがまためんどくさい。僕はむずくて諦めました。 じゃあVirtualBoxは?となりますが、これはこれでキーボードのキャプチャ、解像度の調整、(これは想像ですが)Web開発しようとしたらポートの開放とかめんどいと思います。あとメモリをホストOSから分けてもらってるので動作がもっさり。
というわけで結局デュアルブートに落ち着きました。Ubuntu最高!winは雑魚!
デュアルブートのやり方
UbuntuとWindowsのDualboot環境を構築する | UnFlexFlex
基本的には上のサイトに全部書いてあるので、注意点だけ紹介。
0.Windowsのプロダクトキーを控えておく
万が一データが全部ふっとんだときに備えてプロダクトキーを控えます。
【Windows 10対応】インストール済みのWindows OSのプロダクトキーを調べる:Tech TIPS - @ITによると、
wmic path SoftwareLicensingService get OA3xOriginalProductKey
で確認できます。
1.高速スタートアップを無効にする
ここは特になし。もしかしたらやらなくてもOKかもしれないが僕はやりました。
2.Windowsのドライブを縮小
ここも手順通り。僕はデスクトップ機が70GBくらい使ってるので80GBをubuntuに割り当てましたが、ほんとにwindows使わないので160GBくらい割り当てても良かったかもしれない・・・。ちなみにデスクトップでは個人でpythonの開発とかやってます。他の言語はやってないです。
参考までに、ドライブをいじる前のパーティションを載せときます。 下段のディスク1は下で作るUSBです。
3.Ubuntuをダウンロード
どうせ日本語入力するのでJapanese Remix落としましょう。
4.USBをFAT32形式でフォーマット
ここもそのまま
5.UNetbootinでUSBにLiveCDを書き込む
書き込み先を間違えないように。
MateBook13はF2でBIOSに入れます。ここでUSB以外をDisableにしてUSBから起動するようにしましょう。これは後で戻さなくても普通に動いてます。
7.OSのインストール
ここで注意なのですが、インストールしようとすると、ウィンドウの下が見切れてボタンが押せないのでインストール出来ません。これは解像度が高いからubuntuが自動で2倍に拡大してるためで、「設定>デバイス>ディスプレイ>サイズ調整>100%」を選択すれば普通に戻ります。その代わりめっちゃ文字が小さくなります。まぁ耐えられなければ好きな3:2の解像度を選んでください。
インストールは「それ以外」を選ぶのですが スワップ領域は作らなくていいらしいです。実際僕も作ってないですが2GB確保されてました。 参考:https://kledgeb.blogspot.com/2018/04/ubuntu-1804-bios-2-biospcubuntu-1804.html
後は手順通りのはず。インストールしたらフォルダ名を英語にするのを忘れずに。
Matebook 13を買った。
Matebook 13 を買いました。そもそもの発端は6年間使い続けたASUS x202eが電源入らず、充電もできなくなったことでした。まぁ買った後に電池パックを外してつけなおしてみたら普通に動いたんですが、どちらにしてもメモリ4GB&Ivyのcorei3じゃ動作遅すぎるので、x202eは弟のPC勉強機になりました。軽く使ってみた感想としては感動ですね。画面がきれい、電池が持つ(x202eは1.5hしか持たなかった)、キーが光る、音が良い、手触りが良い。などなど。まだ連休中で家でゴロゴロしてて、持ち出して触れてないから細かいレビューは後で上げます。多分。 ちなみに買って速攻ubuntu入れました。もうWindows触れない・・・。WindowsなしでハイスペノートPCあれば迷わず買ったんだけどなぁ。
django で自分で作ったファイルをダウンロードさせる
どういうときの話?
例えばユーザーの入力によって動的にファイルを作り、そのファイルをModelのデータベースに保存1させつつ、ユーザーにダウンロードさせたいとき
下準備
# @settings.py MEDIA_ROOT = os.path.join(BASE_DIR, 'media/') MEDIA_URL = '/media/'
参考
設定 | Django documentation | Django
Djangoで、ファイルダウンロード | NARITO BLOG
スラッシュの過不足があったりするとエラーが出るので注意。
# @urls.py from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # ... the rest of your URLconf goes here ... ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
これはユーザーだけじゃなくて、自分でアップロードする場合にも必要。これは開発時の設定なので注意
参考
静的ファイル (画像、JavaScript、CSS など) を管理する | Django documentation | Django
# @models.py from django.db import models class FileModel(models.Model): file = models.FileField(upload_to='files/')
足りない所は想像力で補ってください。
ファイルをModelに保存する
from django.core.files.base import ContentFile from .models import FileModel string = 'this is sample file content' myfile = FileModel() content = ContentFile(string) myfile.file.save('file_name', content)
参考
モデルフィールドリファレンス | Django documentation | Django
こうするとDBに登録されるのでフィルターとかソートとかして取り出せる(はず)。
同名のファイル名で上書きすると、suffixが付いたファイルが新たに作成されて、そちらがDBの指すファイルの実体となる。もとのファイルが削除されるわけではない。
html側は、
<a href="{{ uploadfile.file.url }}" download="{{ uploadfile.file.name }}">{{ uploadfile }}</a>
のようにdwonload属性を使うのが手軽でいいと思う。
参考
Djangoで、ファイルダウンロード | NARITO BLOG
-
この言い方は正しくないが↩