- ヘッダの数が多い場合にスクロールするように修正 (けど、ScrollIntoView による挙動が微妙)。
- sidetoc を表示していない場合でもヘッダジャンプしたくなったのでコンポーネントを削除しないようにした。
- ヘッダがない場合に微妙な隙間ができていたので表示しないように修正した。
ついでに 1.6.1 もリリースしていて codeblock 内のコメントがヘッダとして認識されていたのを修正した。
ついでに 1.6.1 もリリースしていて codeblock 内のコメントがヘッダとして認識されていたのを修正した。
default | minimum |
---|---|
エディタ領域だけ表示して使う場合にヘッダ部分を狭くして広く使いたいと思うことがよくあるのでオレオレコマンドを書いてみた。
window 幅をもうちょっと狭くできるようにしたいので init.js に ↓ も記述しておく。
inkdrop.window.setMinimumSize(400, 400)
キーマップも定義
'body': 'ctrl-1': 'mycmd:toggle-distraction-free' 'ctrl-2': 'mycmd:toggle-sidebar'
ゴリゴリ感はあるし、ウインドウ移動のがしづらいのはあるけど (ドラッグ可能な領域を 5px だけ残してる)、期待した挙動にはなってるので使用してみる。 気になるところを js や css でいじれるのがやっぱり良い。
Git for Windows SDK + ConEmu で日々過ごしていたのだけど Windows Terminal 1.0 が出たということで乗り換えた。
とりあえず動かしたい場合の記事を探すと Qiita が引っかかるのが便利なのか疑問に感じるところではあるけど、ありがたく手順を参考にさせてもらう。
ConEmu で指定していた設定 (commandline) をそのまま書いたら動いた。アイコンは手頃なのが無かったので msys2.ico を適当に指定。
{ "guid" : "{f1da5d94-db6f-46ea-82bc-73098ca160ec}", "closeOnExit" : true, "colorScheme" : "Solarized Light", "commandline" : "C:\\git-sdk\\git-cmd.exe --no-cd --command=usr/bin/zsh.exe -l -i", "cursorColor" : "#FF8040", "cursorShape" : "filledBox", "fontSize" : 12, "historySize" : 9001, "icon" : "C:\\git-sdk\\usr\\share\\git\\msys2-32.ico", "name" : "ZSH", "padding" : "5, 0, 0, 5", "snapOnInput" : true, "startingDirectory" : "%USERPROFILE%", "useAcrylic" : false }
明るい画面が苦手になってからよくあるデフォルトの暗いテーマを使うと単に薄暗くて見づらいだけになってしまうので明るめの色設定をしている。とりあえず使い始めたかったのでデフォルトで使える Solalized Light を指定。
zsh が動くし peco も動いたし、折返しで表示が崩れるのもマシになった気がする。ConEmu で一番気になっていた常時 cpu を数 % 使用するのが無くなったのが一番嬉しい。フォントは ConEmu で使っていた Migu 1M にしようかと思ったけど設定したら微妙だった。デフォルトフォントに戻したらいい感じだったのでそのまま使用中。Windows Terminal 用に開発したフォントらしい。自分環境のフォントがどんどんデカく太くなっていってる気がするけど・・・気にしない。
cmd.exe を管理者モードで起動したいとか、もうちょっと行間 (line space) を広げたいとかはあるけど、主に無駄な cpu 数 % 使用が無くなったので満足している。
ログイン状態がおかしいなと思っていたら 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 である必要はなくて単純なページ更新方式でいいのだけど。