Using the DACE Framework for Hotel Front‑End Development: Architecture, SSR, and Practical Lessons
This article details a front‑end engineer's experience building a hotel mini‑program with the DACE framework—covering its React‑based SSR architecture, module organization, data fetching strategies, custom components, webpack code‑splitting, and the challenges and insights gained during development, integration, and deployment.
The author, a front‑end developer at Qunar, introduces the DACE framework, which combines React 16, React‑Router 4, Redux, and Webpack 4 to enable server‑side rendering (SSR) and faster first‑paint performance.
Related Technologies
DACE adopts an isomorphic development model, providing default Webpack configurations for automatic code splitting and allowing custom extensions for business‑specific bundling.
Project Initiation
A demo project was created to explore DACE, focusing on page routing via src/pages and using react‑router for clean URLs.
Project Structure
├── README.md # ReadMe
├── package.json # Project configuration
├── src # Source code
│ ├── common # Shared components
│ ├── pages # DACE route entry points
│ │ └── pagePath # Individual page components
│ │ └── component # Feature modules inside a page
│ ├── lib # Utility methods
│ └── styles # Global styles
└── dace.config.js # Webpack configurationComponent Development
Page components receive data through props, avoiding direct connect to Redux unless a state change impacts the whole page (e.g., order status). Simple UI toggles are handled with local setState.
// Example JSX structure
<div className='wrapper'>
{hasData ? (
<React.Fragment>
{/* Order status */}
<OrderStatus orderInfo={data.orderInfo} />
{/* Check info */}
<CheckInfo tyingInfos={tyingInfos} />
</React.Fragment>
) : (
<div className='error-wrapper'>...</div>
)}
</div>Common Components
An Icon component centralizes icon usage, while a flexible Modal component supports various layouts and animation handling. To prevent background scrolling when a modal appears, the following utility is used:
const banScroll = (show) => {
if (typeof window !== 'undefined') {
document.documentElement.style.overflow = show ? 'hidden' : '';
document.body.style.overflow = '';
const bodyEl = document.body;
if (show) {
this.top = document.documentElement.scrollTop;
bodyEl.style.position = 'fixed';
bodyEl.style.top = `${-this.top}px`;
} else {
bodyEl.style.position = '';
bodyEl.style.top = '';
window.scrollTo(0, this.top);
}
}
};Project Integration & Release
In the beta environment, devServer.proxy cannot be used, so Nginx is configured for proxying. Server‑side data requests must forward client cookies via ctx.req.headers to obtain user‑specific order details.
// index.jsx – getInitialProps
static getInitialProps = (ctx) => {
const { store, query, req } = ctx;
store.injectReducer(reducer);
return store.dispatch(fetchData(query, req.headers));
}; // action.js – fetchData
const fetchData = (fetchParams, fetchHeaders) => async (dispatch, getState) => {
const state = getState();
const { pageParams, pageHeaders } = state.hotelOrderData;
const params = fetchParams || pageParams;
const headers = fetchHeaders || pageHeaders;
await axios.get(fetchDetailData, { headers, params })
.then((data) => {
dispatch(fetchDataSuc(data));
})
.catch((err) => {
dispatch(fetchDataFail(err));
});
};Page Display Examples
The UI shows different states for successful or failed first‑page data requests, and distinguishes between actions that require a Redux dispatch (e.g., canceling an order) versus local UI state changes handled by setState. Webpack code‑splitting isolates third‑party libraries and non‑essential components to reduce bundle size and improve first‑paint speed.
Reflections & Gains
Building the project from scratch highlighted the importance of consistent coding standards, deepened knowledge of React, Redux, PropTypes, and Webpack proxy configuration, and taught practical SSR techniques such as using static methods for data pre‑fetching. The experience also underscored the need for close collaboration with backend teams to align API contracts and handle edge cases during integration.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Qunar Tech Salon
Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
