【React】子コンポーネントから親コンポーネントへデータを渡す
子が好きなタイミングで親のメソッド実行する
Vueと同じように子コンポーネントの好きなタイミングで親コンポーネントに作成したカスタムイベントを発火させることができる。その時の引数としてデータを受け取る、という流れである。
注意点として、親コンポーネントではカスタムイベント={メソッド名}
として関数への参照を渡す。
子から送られてきたデータは引数としてメソッド内で受け取ることができる。
// 親コンポーネント handleMyEvent = (value) => { console.log(value) // 3 } <Counter myEvent={this.handleMyEvent} /> // 子コンポーネント <button onClick={() => this.props.myEvent(3)} >myEventを発火</button>
データフローは単一方向
データフローは単一方向、つまり「親から子へ」という一方通行である。 親のデータを子から変更することはできない。子のデータは親からもらうので、もちろん子は親のデータに依存している。 具体例で説明しよう。
親が貧乏になると一緒に子どもも一緒に貧乏になる。一方で、子どもが親からもらったお小遣いを使い果たしても親は貧乏にならない。子どもは親のお金を勝手に使うことはできない。じゃあどうするか?子どもは親に「お金が欲しい。いくら欲しい」ということを伝えるのだ。親は事前にお金がなくなったら言いなさい、と子どもにカスタムイベントを渡している。あとはそれを、子どもが引数つき(なくてもよい)で、好きなタイミングで実行するのだ。親は我が子の助けが来たらお金をあげようとずっと待ち構えている(イベントを購読)。親はそのイベントが起きるとまたお金をあげる、つまり任意の関数を実行するのである。
controlled component
controlled component
とは自分でstate
を持たないコンポーネントのことである。
props
で親から全てのデータを受け取り、データを変更したい時は親からもらったイベントを発火させる。
そして親のメソッド内でデータを変更する。
つまり、その名の通り完全に親に依存するコンポーネントである。
【Git 】git switchでリモートブランチをローカルに持ってくる
リモートブランチと同じ名前のブランチをローカルに持ってくる
新しいコマンドのgit switch
が便利!
$ git switch remote_branch_name
もしうまくいかない場合は$ git fetch
を実行してローカルのリモート追跡ブランチを更新してください。
リモートブランチと違う名前のブランチを作成する必要がある時
$ git checkout -b branch_name origin/branch_name
branch_name
は自分で命名できる。
【React】propsとstateの違い
props
- 親コンポーネントからもらうデータ
- 読み取り専用で変更することはできない
state
親からもらうデータを加工したい
親からもらうデータを加工したい時はstateに格納すればいい。
// 親コンポーネント <Counter number={7}> // 子コンポーネント state = { numberFromParent: this.props.number }
初期値を別に設定したい時は、任意の関数内でsetStateを使えばいい。
// 親コンポーネント <Counter number={7}> // 子コンポーネント state = { numberFromParent: 0 } // クラスのインスタンメソッドとして定義。この書き方はbabelによってコンパイルされるため、正式なJSの記法ではない。 doubleNumberFromParent = () => { const newNumber = this.props.number * 2 this.setState({numberFromParent: this.state.numberFromParent + newNumber}) }
上のコードではsetState
の引数にオブジェクトを渡している。setState
にオブジェクトを渡すと最新のstate
であることが保証されていないので注意が必要だ。参考 : ReactのsetStateについて整理してみた - Qiita
【Rails】静的ファイルのダウンロード機能を実装する
動的ファイルならコントローラーを経由する必要がある。しかし静的ファイルならもっと簡単にできる。
public/
にfoo.txt
を作成download: "ダウンロードする時のファイル名"
という文法でviewに書く
<%= link_to 'foo.txtをダウンロード', '/foo.txt', download: 'foo.txt' %>
ちなみにdownload: ''
を書かないとその静的ファイルがそのまま表示される。
その時、rails server
のログを見ていても変化はない。何が起きているのか分からなくてクッソハマった😵
【DB設計】自己参照する多対多の関係を分かりやすく説明する
多対多の復習
自己参照する多対多の関係を理解するには、多対多の関係を理解する必要があります。 大学の授業と生徒の関係を例にとって考えてみます。
まずは学生目線で考えましょう。学生一人が取れる授業の数はいくつでしょうか? 1つでも2つでも3つでも、いくつでもいいですよね。0でもいいかもしれません。 つまり学生:授業 = 1:多となります。
次は授業目線で考えます。一つの授業に参加できる学生は何人でしょうか? 1つの講義にはたくさんの生徒が出席しますね。よって授業:生徒 = 1:多となります。
では学生:生徒の関係はどうなるでしょうか? どちらか一方を1と固定しても、どちらも1:多になってしまいました。このような場合は多:多となります。このように多:多の関係の見つけ方はどちらも1対多になった時となります。
ER図を書いてみよう
それでは学生と授業のデータベース設計をしてみましょう。こんな感じになります。
多対多の関係を管理するには中間テーブルを使います。中間テーブルを見れば、「誰が」「どの授業を」とっているのかが分かります。
select * from students_lectures;
自己参照する多対多の関係
ようやく本題です。今回はTwitterのフォロー関係を例に考えます。 ユーザー1人がフォローできる人数は複数です。よって1対多となります。 一方で1人のユーザーは複数人からフォローされます。したがって、フォローするユーザー:フォローされるユーザーは多:多となります。
ここまでは普通の多対多と同じです。しかし決定的に違う点ひとつがあります。何でしょうか?
ER図を書いてみる
friendshipsテーブルを見れば、「誰が」「誰を」フォローしているかが分かります。
学生と授業の例との違いは何でしょうか?
テーブルが一つ少ないですね。中間テーブルのfriendships
のカラムであるfollowing_user_id
とfollowed_user_id
はどちらもusersテーブルとつながっています。
どうやって結合する?
中間テーブルを見れば、誰が誰をフォローしているのか、誰が誰によってフォローされているのか、ということが分かります。
フォローしている人もフォローされている人も名前にして表示したい時はどうしましょう? usersテーブルと結合しますよね。
どちらも同じテーブルを参照しているので結合できない?
結合を考えましょう。usersテーブルをもう一つ作らないと結合できないのでしょうか?
答えはNoです。usersテーブルに別名を付けるだけで簡単に結合できます。 usersテーブルとusersテーブルを結合して新しいテーブルを作ります。このように自分自身との結合を自己結合と言います。
自己参照とは?
自己参照とは、参照するテーブル(エンティティ)が自分自身である場合をいいます。今回の例ではフォロー関係を理解するためにusersテーブルが自己参照をしています。
まとめ
- 多対多の関係は、1対多 + 1対多である。
- 多対多の時は、1対多となるような中間テーブルを作る。
- 自己結合とは、1つのテーブルにそれぞれ別名を与えて2つのテーブルと見立てて結合することである。
- 自己参照する多対多の関係は、多対多 + 自己結合で解決できる。
RubyMineの初期設定
ピープ音を消す
macのアラート音を消す。つまり、通知音量を0にする。slackなどの他のアプリの音は聞こえるのでこれで問題ない。
右の目立つ縦線を消す
- シフトを2回押して「wrap guide」と検索する。
- Hard wrap guideのForegroundのチェックを外す。
ちなみに、ここでインデントラインの色を変更できる。
折り返しをできるようにする
Editor > General > Soft WrapsでSoft-wrapするファイルを追記する。 ファイル名はセミコロンで分けることに注意する。 全てのファイルを選択する方法を知りたい><
画面分割したタブ間で移動するショートカットの作成
設定画面で、左上からsplitterで検索。 Goto Next Splitterに好きなキーを割り当てる。
入力モード中のjjでエスケープする
右下のVのロゴをクリックして.ideavimrc
に追記する。
inoremap
はインサートモード時のキーマッピングを作成する記述である。
inoremap jj <Esc>
注意
ターミナルから読み込んでもエラーになってしまう。設定を反映するにはRubyMineを再起動する必要がある。
ショートカットキーの設定
.ideavimrc
"大文字小文字の区別なし set ignorecase "検索時に大文字を含んでいたら大/小を区別 set smartcase "検索対象をハイライト "ハイライトを消す場合は:noh[l] set hlsearch "スクロール時に表示を10行確保 set scrolloff=10 "x キー削除でデフォルトレジスタに入れない nnoremap x "_x vnoremap x "_x "vv で行末まで選択 vnoremap v ^$h "Yでカーソル位置から行末までヤンクする nnoremap Y y$ "選択範囲のインデントを連続して変更 vnoremap < <gv vnoremap > >gv "ノーマルモードでもリターンキーで改行 nnoremap <CR> A<CR><ESC> nnoremap <Space> i<Space><Esc> " j, k による移動を折り返されたテキストでも自然に振る舞うように変更 nnoremap j gj nnoremap k gk " vを二回で行末まで選択 vnoremap v $h " 動作環境との統合 " OSのクリップボードをレジスタ指定無しで Yank, Put 出来るようにする set clipboard=unnamed,unnamedplus "screen利用時設定 set ttymouse=xterm2 " マウスの入力を受け付ける set mouse=a " インサートモードから抜けると自動的にIMEをオフにする set iminsert=2 "tab/identの設定 set shellslash set expandtab "タブ入力を複数の空白入力に置き換える set tabstop=2 "画面上でタブ文字が占める幅 set shiftwidth=2 "自動インデントでずれる幅 set softtabstop=2 "連続した空白に対してタブキーやバックスペースキーでカーソルが動く幅 set autoindent "改行時に前の行のインデントを継続する set smartindent "改行時に入力された行の末尾に合わせて次の行のインデントを増減する " ESCキー2度押しでハイライトの切り替え nnoremap <Esc><Esc> :nohlsearch<CR><ESC> " 入力モード中に素早くJJと入力した場合はESCとみなす inoremap jj <Esc> " インクリメンタル検索 (検索ワードの最初の文字を入力した時点で検索が開始) set incsearch
カラースキームの変更
Vimだと難しいカラースキームの微調整もRubyMineなら簡単にできる。