## Getting started with React [![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls) [![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki) --- ## How to use the demo >This demo will give you a quick start for using Sonic with React. ### Dependencies Node Version > 7.0 ### Installation ```bash git clone https://github.com/Tencent/VasSonic.git cd /sonic-react npm install # Install project dependencies ``` ### Usage ```bash npm run build # Builds the application to ./.next npm start # Start the development server ``` Now you can visit http://localhost:3000/demo to view this demo using Mobile Emulation Mode in Chrome dev tools. ## How to use Sonic on server-side >NOTE: This demo using Server Side Rendering (SSR) with [Redux](https://redux.js.org/), [Next.js](https://github.com/zeit/next.js/) and [Koa2](http://koajs.com/). 1. Add comment tags to separate **template** and **data blocks** in html files which will be published from the server. The **data blocks** should begin with a html comment like `` and close with ``(the moduleName is custom). And the other part of the html is called **template** in Sonic. In this demo, it is implemented like the code shown below. - Below is the origin html, we will generate comment tags according to the `data-sonicdiff` attribute and the script block including `__NEXT_DATA__`: ```HTML … …
… …
… … ``` - Then, we have a transform function at server side: ```js function formatHtml(html) { const $ = cheerio.load(html); $('*[data-sonicdiff]').each(function(index, element) { let tagName = $(this).data('sonicdiff'); return $(this).replaceWith('' + $(this).clone() + ''); }); html = $.html(); html = html.replace(/\s*__NEXT_DATA__\s*=([\s\S]+?)<\/script>/ig, function(data1) { return '' + data1 + ''; }); return html; } ``` - After the transform, the latest code user will received will be like: ```HTML … … +
… …
+ … … + + ``` 2. Intercept the html response from server and use [sonic_differ](https://github.com/Tencent/VasSonic/blob/master/sonic-nodejs/common/diff.js) module to process the response. ```js server.use(async (ctx, next) => { await next(); // only intercept html request if (!ctx.response.is('html')) { return; } // process non-sonic mode if (!ctx.request.header['accept-diff']) { ctx.body = ctx.state.resHtml; return; } // use sonic_differ module to process the response let sonicData = sonicDiff(ctx, formatHtml(ctx.state.resHtml)); if (sonicData.cache) { // 304 Not Modified, return nothing. ctx.body = ''; } else { // other Sonic status. ctx.body = sonicData.data; } }); ``` For more details please refer to [server.js](https://github.com/Tencent/VasSonic/blob/master/sonic-react/server.js). ## How to use Sonic on client-side Handle the response from mobile client which include Sonic response code and diff data in `componentDidMount()`. ```js componentDidMount() { // handle the response from mobile client which include Sonic response code and diff data. this.getSonicData((status, sonicUpdateData) => { switch (status) { // here, we only process the case when data updates case 3: // update the Redux store based on changes from the mobile client let initState = sonicUpdateData['{initState}'] || ''; initState.replace(/\s*