\n
完整程式碼:Progress Navigation | Codepenopen_in_new
在某些應用裡,偶爾會需要像是或是等long-term navigation的操作體驗,每一個步驟都不太能立刻完成,甚至需要等到下次登入時再繼續進行。最近要以React來實作這般功能時,發現不如預期中容易,關鍵在於此功能必須滿足:
從工程團隊的角度來看,程式碼本身應該要簡潔明確,核心的routing邏輯應該抽成獨立模組來維護,且不同team member應該要能平行且專注於刻出不同步驟的內頁。
根據產品需求,這個功能在未來可能加入新的擴充,例如:
因此,架構上可以採用react-router來維護每個獨立的步驟,並且給定每個步驟的唯一路徑:
const App = () => ( <BrowserRouter> <Switch> <Route exact path="/page/1" component={StepOne} /> <Route exact path="/page/2" component={StepTwo} /> <Route exact path="/page/3" component={StepThree} /> <Route component={StepOne} /> </Switch> </BrowserRouter>)
每個步驟之間必須由一個獨立模組來管理跳頁,還要保持步驟內頁可以掌控整體流程的權限,還要監聽頁面切換以便蒐集user的操作行為,一個可靠的作法就是模仿react-router中的,自己實作一個步驟間路由的HOC,封裝react-router的 method,並且提供之類的method給步驟內頁元件來掌控整體流程:
const withProgressRouter = (WrappedComponent) => { class HelperComponent extends Component { goToPath = (path) => { const { history } = this.props; // 可以在此與backend互動 history.push(path); }
render() { return ( <WrappedComponent goToPath={this.goToPath} {...this.props} /> ); } } return withRouter(HelperComponent)}
不同步驟之間共享的UI(例如、)可以獨立成一個Component:
const ProgressRouter = ({ onBackClick, onNextClick, children }) => ( <> <button onClick={onBackClick}>back</button> <button onClick={onNextClick}>next</button> <hr /> {children} </>)
步驟內頁只要透過HOC提供的就能自由地控制整體流程,同時也能共享同一套切換步驟的UI,完全專注於步驟內頁的設計:
const StepOne = withProgressRouter(({ goToPath }) => ( <ProgressRouter onBackClick={() => goToPath('/step/1')} onNextClick={() => goToPath('/step/2')} > Step One </ProgressRouter>))
const StepTwo = withProgressRouter(({ goToPath }) => ( <ProgressRouter onBackClick={() => goToPath('/step/1')} onNextClick={() => goToPath('/step/3')} > Step Two </ProgressRouter>))
const StepThree = withProgressRouter(({ goToPath }) => ( <ProgressRouter onBackClick={() => goToPath('/step/2')} onNextClick={() => goToPath('/step/3')} > Step Three </ProgressRouter>))
如何實作分頁式的Progress Navigation?
如何實作分頁式的Progress Navigation?