ログイン状態がおかしいなと思っていたら https にしていないからだと書いてあった。
ダッシュボードからボタンポチッとで変更終了。
特に問題は無さそう (?)。
ログイン状態がおかしいなと思っていたら https にしていないからだと書いてあった。
ダッシュボードからボタンポチッとで変更終了。
特に問題は無さそう (?)。
inkdrop でサイドバーにヘッダーを表示するプラグインをアップデート。
主な内容はヘッダ移動するコマンドを二つ追加したこと ( sidetoc:jump-prev
、sidetoc:jump-next
)。
一つのノート の記載量が多くてもサイドバーでアウトラインを確認しつつヘッダジャンプもサクサクできるので便利。vim plugin も入れているのでカーソル移動がいろいろ捗る。
keymap.cson 抜粋
'.CodeMirror.vim-mode:not(.insert-mode):not(.key-buffering) textarea': 'ctrl-n': 'sidetoc:jump-next' 'ctrl-p': 'sidetoc:jump-prev'
また、あまり分かってなかったので気軽にイベント登録してたのをちゃんと解除するように見直した (componentWillUnmount
だいじ)。
vim plugin がプレビュー表示でもキー操作できるようになったので、sidetoc もヘッダのハイライトを連動したり対象ヘッダに移動したりをしたいのだけどやり方がまだよく分からない。
最近はてなブログでエントリを書こうとすると未ログイン状態になってて、ログインしようとするとパスワードが違うとい割れるけどログインしようとしている Id でログインしてる。自動ログインのチェックボックスを解除しても自動ログインを始めるからエンドレスループ。いつのまにかちゃんと?ログインしたことになってたり、ログアウトしてもログイン状態になってるしでタイムラグが有る感じ。書く気力が削がれていく辛い。
"use babel"; import { Dispatcher } from "flux"; export default new Dispatcher();
inkdrop plugin の機能追加中にどうしたら実現できるんだろうと詰まったのだけど、結果 flux を利用して実現できた。flux よく分からんなと思っていたけど connecting dots したかも?
表示する React.Component が持っている状態を使ってイベントを発生させたいケース。具体的には特定の行にジャンプさせたい。
他にも componentWillUnmount でイベントを解除しないと行けないとか、更新検知が微妙だったあたりも見直せたので GW の活動は効果あったようだ。ほぼほぼできたと思ってたけど、挙動を見ていくと気になるところがぽろぽろ出てくる。
GW 中は React の勉強するかと思い立ったもののまだまだ道半ば (ゴールが見えない)。その自分用の記録。
Web 層は Go + echo でキーワード検索した結果を JSON で返すだけ。CL 層は React で受け取った JSON の内容を表示する単純構成。Web はすぐに完成。CL 層もボタンを押したタイミングで一覧を出せるところまでは React のチュートリアルを見ながらで到達。
ここからが長かった。
React で状態管理をしたくなるが、複数 Component で構築する際に状態をどこに持って管理して、どう伝搬させたらいいのか分からなくてすぐに詰まる。Facebook 推奨の Flux を使えばいいらしいことが分かるので入門記事を漁る。
pub/sub 方式により Action でイベントを発行して Dispatcher が振り分ける。
Store を更新して View が反映する。
連携 | クラス図 |
---|---|
TodoStore.js
class TodoStore extends EventEmitter { createTodo(text) { // ・・・ 略 ・・・ // this.emit("change") } handleActions(action) { switch(action.type) { case "CREATE_TODO": { this.createTodo(action.text); } } // ・・・ 略 ・・・ // } const todoStore = new TodoStore(); dispatcher.register(todoStore.handleActions.bind(todoStore));
Todos.js
TodoStore.on("change", () => { this.setState({ todos: TodoStore.getAll() }) })
dispatcher と emitter の二つが出てくる。使い分けはなんとなく感じるけど漠然としてる。
これでもいいのだけど状態管理するのに分かりづらいので他の方法が無いかを探し始める。
とくに状態を伝搬させていくのが辛い。
すぐに Redux がヒットして、説明を読む分にはこれがいいのではないかと入門を漁る。
Redux の Store の特徴として、flux とは異なり、一つの Store のみ存在することです。すべての状態データを一箇所で管理することになるのでシンプル性を維持することができます。画面及びアプリケーションの初期化は Store から始まります。
middleware を使うと reducer の組み合わせで柔軟な処理を実現できるっぽい。
ここまできて、大げさすぎるしよく分からんくなってきたのでもっと簡単にできないかと探し始める。
“接続する (hook into)” ための関数です。 フックは React をクラスなしに使うための機能ですので、クラス内では機能しません
レンダリングの後に処理を動作させる
const [count, setCount] = useState(0) useEffect(() => { console.log('hello useEffect') }) return ( <> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </> );
prop drilling 問題を解決する一案。
const Context = createContext() const Mago = () => { const { money } = useContext(Context) return <p>{money}円</p> } const Kodomo = () => <Mago /> const Oya = () => { return ( <Context.Provider value={{ money: 10000 }}> <Kodomo /> </Context.Provider> ) }
const afterRef = useRef(); // useEffect の cleanup で参照する場合はコピーしないとだめ? (ワーニングが出る) useEffect(() => { document.title = `You clicked ${count} times`; const copyRef = afterRef; return () => { copyRef.current.innerText = count; }; }); return ( <span ref={afterRef}>{count}</span> )
コンポーネントの中で呼び出されるHooksはいつなんどきでも必ず同じ順番で同じ回数呼び出されること!
簡単にいうとつまり if や for の中に Hooks を入れて「場合によって Hooks の順番や実行回数が変わる」ことを禁止しています。また、早期 return による実行回数のズレにも注意です。 基本的には関数コンポーネントのトップレベルかつ最上部に Hooks を書き並べておけば大丈夫でしょう。
Redux のあたりで出てきた Reducer と createContext を使えば手軽にできるじゃんと思い立つ。
function App() { const [store, dispatch] = useReducer(reducers, Store); return ( <div className="App"> <AppContext.Provider value={{ store, dispatch }}> <Header /> <Content /> </AppContext.Provider> </div> ); }
const ToDoPane = () => { const { store, dispatch } = useContext(AppContext); return ( <div> {store.toDoList.map((todo) => ( <ToDoItem key={todo.key} title={todo.title} description={todo.description} onClick={() => dispatch({ type: "remove", todo: todo })} /> ))} </div> ); };
export default function reducer(store, action) { switch (action.type) { case "add": return store.add(action.todo); case "remove": return store.remove(action.todo); default: } return store; }
いい感じにできた気がしたのだけど挫折
App()
が何回も呼ばれるもっと簡単にやりたいので探し始める。オレオレでやりたかったことができるじゃんで飛びつく。
200 bytes to never think about React state management libraries ever again
ページ構成 | クラス図 |
---|---|
react-modal でモーダル表示もしてみた。
こねこねやった結果がこのあたり。
最初の描画でデータを取得して反映する方法がよくわからず (描画のループになるとか、描画中に反映できないエラーとか) Initializer Component をかますようにしてみた。正当な方法はどうやるんだろか。
hooks を使うときは新しいオブジェクトを返すお決まりなのでやり方。
配列に追加
[...state.values, newValue]
配列のある要素の変更
[ ...state.slice(0, action.index), modifiedValue, ...state.slice(action.index + 1) ]
オブジェクトの変更
Object.assign({}, state, { completed: true, name: "new name" });
パズルみたいでアレをやるためにはどうしたらいいのかを結構考えないといけなくて、ちょっとズレてると大失敗する印象。
いまどきのフロントエンド開発は大変だ。
本命のツールは作れずで今に至る。疲れた。 そもそも React である必要はなくて単純なページ更新方式でいいのだけど。
↑ 新規購入
GeChic モバイルモニタ On-Lap 1101F レトロ調カラー 11インチ フルHD解像度 IPS液晶 24Hz入力対応
↑ もともと使っていたファミコンっぽい色のモニタ。気に入ってたけど 2 年ちょいでダメになったっぽい。Switch 用のモニタとして使っていたのだけど GW 初日に画面出力されなくなった。辛かった。PC に繋いだら出力されたので USB-C のコネクタか Dock が問題なんだろうと思って両方追加で買ってしまったのだけど結局モニタだった。HDMI - mini HDMI ケーブルが問題の可能性もあるけどこれ以上購入して検証するのもだるいので保留中。最悪、本体修理で 1ヶ月の可能性もありそうだったのでよかった。
新しいディスプレイは 11 inch → 13.3 inch で大きくなった上に表示も綺麗なので気に入っている。音量の変更ができないのかと思って 1 時間ぐらいガックリしていたけど (その発想はなかった) 、横のスイッチをぽちぽちしてたら変更できることが分かって一安心。
ある時期からでかい画面 (といっても 21 inch とか) を見るのがしんどくて、仕事中もノートpc の 13.3 inch ディスプレイを超えるとしんどくて見てられなくなる病なので (最近だいぶ良くなってきたけどつらい) 、ちょうどよいサイズ。このモバイルモニタと apple keyboard を使えばいい感じの環境になりそうな気がしているので家で試してみていい感じだったら会社でもスタンド付きで買ってもらいたいなぁ。
v10.0 からリポジトリパス(/var/opt/gitlab/git-data/repositories
配下のパス)をハッシュ化する機能がリリースされていて、v12.0 でデフォルト ON に変更された。
プロジェクト名やグループを変更した際にディスクのパスが変更されていたけど、プロジェクトID を hash 化したパスを使うことでそれがなくなった。特定のグループに偏ることなくフラットに配置されるので色々とディスクに優しくなるらしい。
管理画面でプロジェクトのパスを確認できる。
To access the Projects page, go to Admin Area > Overview > Projects and then open up the page for the project. The “Gitaly relative path” is shown there, for example: "@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git"
新規のプロジェクトを Hashed Storage にするかは管理画面で設定できる。
1. Go to Admin > Settings > Repository and expand the Repository Storage section. 2. Select the Use hashed storage paths for newly created and renamed projects checkbox.
ID 指定で migration できる。
sudo gitlab-rake gitlab:storage:migrate_to_hashed ID_FROM=50 ID_TO=100
逆に元のプロジェクト名のフォルダ構成に戻す方法もある
sudo gitlab-rake gitlab:storage:rollback_to_legacy
Rails console から該当プロジェクトを引く方法もある。
Project.find(16).disk_path ProjectRepository.find_by(disk_path: '@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9').project
いろいろ機能追加されていってて便利に。
dokuwiki に前からある plantuml plugin はそのままじゃ動かなくなってて、代わりに plantumlparser ができてた。 ただ、サーバーを指定できなくて plantuml 公式の方にリクエストを投げるしかなかった。 せっかく社内に docker で plantuml サーバーを立てたのでこちらに投げたいと思っていたらちょうど MR が作成されてた。
MR がマージされたので、さっそくインストールしてセットアップ完了。
plantuml を動かせる環境が増えたのでまた一つ便利に。