mmjに入社してから、Reactでフロントエンドのコーディングをしています。
最初は各ページに一つのrouteをつけて管理していましたが、そうすると、関連ページのstatusが共有できなくて、全部propsで管理するか、全局変数で共有することをせざるを得なかったことがあります。全部をprops使って各ページの間に渡すと、検索条件等でもpropsに指定しなくてはなりません。propsが膨大になって、可読性が落ち、管理がしづらくなっていました。
そこで弊社のtk先生の指導の下で(ほとんどはtk先生が書いてくれました)、routeの構造を改造しました。
この改造で、同じDomainを1つのrouteにまとめました。
routeは2つの部分から構成されます。各ページのrenderer、と1つの親routeです。
各renderer
各ページに必要なstatusを定義と、そのstatusに対する操作のハンドリングの定義を保存する場所ですので、
各自のstatusを定義しますが、状態は持っていないです。
handleなどのメソッドを定義していますが、状態を引数として渡して、処理した後に返します。
ページを描画するreandererを定義します。rendererに必要な値とメソッドはrendererの引数として渡します。
function renderer(
s: Status,
xi: XXXInfo,
setState:(s: Status) => void,
setViewState: (s: View.Status) => void,
setConfirmStatus: (s: Confirm.Status) => void
): React.ReactNode
従って、このページは状態をもたないです。
親route
routeなので、statusは持っています。
enumのmodeを定義して、各rendererをimportして使います。
import * as View from './xxxRouteView'
Mode,Status,Propsを定義します。
enum Mode {
Loading,
View,
Edit,
Confirm
}
interface Status {
mode: Mode
modeStatus: Loading.Status | View.Status | Edit.Status | Confirm.Status
}
interface Props {
xxxInfo: XxxInfo
}
本当のrendererはこのファイルに定義します。
class XxxRenderer extends Renderer
rendererの中に各ページのsetStateを対応します。
setViewState = (s: View.Status) => {
this.setState({ mode: Mode.View, modeStatus: s })
};
modeによって、各ページを描画します。各rendererに定義したrendererはここで使います。
render(): React.ReactNode {
switch (this.state.mode) {
case Mode.Loading: return Loading.renderer(this.state.modeStatus as Loading.Status)
case Mode.View:
return View.renderer(
this.state.modeStatus as View.Status,
this.props.xxxInfo,
this.setViewState,
this.setEditState,
this.backToTop
)
case Mode.Edit:
return Edit.renderer(
this.state.modeStatus as Edit.Status,
this.props.xxxInfo,
this.setEditState,
this.setViewState,
this.setConfirmState
)
case Mode.Confirm:
return Confirm.renderer(
this.state.modeStatus as Confirm.Status,
this.props.xxxInfo,
this.setConfirmState,
this.setViewState,
this.setEditState
)
}
}
以上が改善したrouteの構造でした。
最後にこの構造まとめ
中国貴州省出身、京都オフィス勤務のエンジニア。前職は大手コンビニ運営部スーパーバイザー。超多趣味。