下記を利用し作ってみました。
- React
- react-hook-from
- TypeScript
- material-ui
- react-bootstrap
- GraphQl
contextやreducerを使用した状態管理。そしてmateria-uiとreact-bootstrapを使用しUIを構築し、Dialogや情報入力蘭を作成しました。
ある程度使い慣れてはいるのですが、改めて学び直しもかねて作成したのですが、大変な面もありますがJavaScriptやTypeScriptが好きな方にとっては楽しくかけたりできるのでいいなと思いました。
その他、GitHub GraphQL APIを使用し簡単な検索機能も作成いたしました。
なかなか安全感を感じるなと思いました。
今回は、主にReact Hooksやアクセシビリティについても大変考慮されているReactなのでそういった内容を書いて行こうと思います。
毎回、状態管理はどういった設計しようかとかUIはどんな操作感や見た目にしようかなど考えます。
なので、思ったより時間がかかりましたが、それなりの物ができたように思います。
最後、静的サイトホスティングサービスのNetlifyを使用いたしました。このことについては特に書くことがありませんので、開発に使用したリストに乗っていますが載せているだけになります。
また、TypeScriptも使用していますので、このことについても触れて行こうと思います。
FLUX
結合関係を複雑にせず、更新の流れを一方通行にし依存関係をシンプルにする。コンポーネントが状態を持つ必要性を最小減にする概念
--- Flow ---
Action → Dispatcher → Store → View → Action → Dispatcher → Store → ...
この繰り返し
useReducer
reducerとは、変化させるものや適用させる関数のことを指します。
本来は、別ファイルに分けるのが一般的かと思いますが、
みやすくするためにまとめて記載しております。
interface State {
counter: number
}
const initState: State = {
counter: 0
}
const addCounter = (n: number) => ({ type: "COUNTER_ADD", payload: n } as const)
const subCounter = (n: number) => ({ type: "COUNTER_SUB", payload: n } as const)
type ReturnType<T extends (...arg: any[]) => any> = T extends (
...arg: any[]
) => infer R ? R : never;
type Action = ReturnType<typeof addCounter | typeof subCounter>
const reducer: React.Reducer<State, Action> = (state, action) => {
switch (action.type) {
case "COUNTER_ADD":
return { counter: state.counter + action.payload }
case "COUNTER_SUB":
return { counter: state.counter - action.payload }
default:
return state
}
}
const [reduserState, dispatch] = useReducer(reducer, initState)
return (
<div>
<span>{reduserState.counter} : reduserState</span>
<p onClick={ () => dispatch(addCounter(1))}>ADD</p>
<p onClick={ () => dispatch(subCounter(1))}>SUB</p>
</div>
)
1つ目の引数には、Reduxのreducerとほぼ同じ仕様の関数を指定し、
2つ目の引数には、初期値を指定。
- 返り値はuseState同様にタプルとなっていて1つ目の要素はステート変数で、
- 2つ目の要素では、Actionを指定するためのDispatch関数になります。
useContext createContext
useContext createContext共にまとめて一枚のファイルに記載されることはおそらく管理の面でもあまり無いかと思います。
こちらもuseReducer同様みやすくするためにまとめて記載しております。
const context = createContext("");
const ConsumerSample = () => {
const Notifications = useContext(context)
//console.log("useContext "+Notifications);
return (
<div>
<div>{Notifications}</div>
</div>
)
};
return (
<div>
<context.Provider value={"useContextによって返却された要素を表示"}>
<ConsumerSample />
</context.Provider>
</div>
)
状態管理をする際、ContextやuseReducerそしてReduxと選択肢があるかと思います。
選ぶ際のポイントはサービス規模や拡張していくことが予めわかっていればReduxの方がいいかもしてません。
なぜなら、ReactのルールからReduxを使用する少々複雑になっていくことが多いからです。
今回僕は、Contextを使用した状態管理を行いました。非常にわかりやすく管理しやすいと感じております。
ですが、Providerに持たせるValueが多くなるにつれて長ったらしくなっているよな気がして来てしまいました。
十分に状態管理の手法を考え、選ばれることをおすすめいたします。
そして、複雑なってしまいかねないので、シンプルに設計することも大事なことかと思います。
useContext
Reactコンポーネントで、階層の離れたコンポーネントに値を渡すHooks関数
読み取り専用です。
createContext
Contextは、createContextによって生成。ProviderとConsumerがあります。
Providerで、value={}で引数を渡し、
ConsumerでProviderでvalueを受け取る
useState
const Field = useCallback((e) => {
setValue({
...value,
[e.target.name]: e.target.value,
})
}, [value, setValue])
言わずもがなだと思いますので、紹介のみにいたします。
以上になります。
他は次回アウトプットしていきます。