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 TodoStoreextends 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> );};
exportdefaultfunction 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 である必要はなくて単純なページ更新方式でいいのだけど。
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。