ind*_*dex 5 mobile express reactjs isomorphic-javascript
我应该如何在我的 reactjs + express 中实现检测移动设备?我使用mobile-detect来确定是否移动,但首先我实现了它,const md = new MobileDetect(window.navigator.userAgent)但我记得window当它加载服务器时不存在。express 部分中的示例应该可以工作,因为这是我唯一可以访问的地方,req但是我如何将它传递到我的 React 应用程序中以供之后使用?
更新
// app.js
...
import { routes } from './routes';
import { match, RouterContext } from 'react-router';
import { renderToString } from 'react-dom/server';
...
const app = express();
app.use(express.static('public'));
app.set('view engine', 'ejs');
app.get('*', (req, res) => {
// routes is our object of React routes defined above
match({ routes, location: req.url }, (err, redirectLocation, props) => {
if (err) { // something went badly wrong, so 500 with a message
res.status(500).send(err.message);
} else if (redirectLocation) { // we matched a ReactRouter redirect, so redirect from the server
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (props) { // if we got props, that means we found a valid component to render for the given route
const reducer = combineReducers(reducers);
const store = applyMiddleware(...middlewares)(createStore)(reducer);
...
const server = http.createServer(app);
const port = process.env.PORT || 3003;
server.listen(port);
server.on('listening', () => {
console.log('Listening on ' + port);
});
// client-render.js
import { routes } from './routes';
import { Router, browserHistory } from 'react-router'
ReactDOM.render(
<Provider store={store}>
<Router onUpdate={() => {scrollTop(); handleNotifs(store)}} routes={routes} history={browserHistory} />
</Provider>,
document.getElementById('app')
);
// routes.js
import AppComponent from './components/app';
import IndexComponent from './components/index';
...
const routes = {
path: '',
component: AppComponent,
childRoutes: [{
path: '/',
component: IndexComponent,
name: 'home'
}, {...}]
}
Run Code Online (Sandbox Code Playgroud)
I accomplished exactly what you are requiring by making my routes module become a function that takes the user-agent. It then simply returns an array or nested routes. Here's an example...
routes.js
module.exports = (userAgent) => {
const md = new MobileDetect(userAgent)
if (md) { // not sure on the syntax of MobileDetect?
return {
// return mobile routes
}
} else {
return {
// return desktop routes
}
}
}
Run Code Online (Sandbox Code Playgroud)
app.js
app.get('*', (req, res) => {
match({ routes: routes(req.headers['user-agent']), location: req.url }, (err, redirectLocation, props) => {
// continue as normal
}
}
Run Code Online (Sandbox Code Playgroud)
client-render.js
ReactDOM.render(
<Provider store={store}>
<Router onUpdate={() => {scrollTop(); handleNotifs(store)}} history={browserHistory}>
{routes(navigator.userAgent)}
</Router>
</Provider>,
document.getElementById('app')
);
Run Code Online (Sandbox Code Playgroud)
On a side note, using this approach we are able to also pass in the auth cookie to the routes so the onEnter methods can redirect if the route is behind login.
Hope this helps! BTW React-Router is the best!! I got to meet the creators in NYC and they're top notch.
| 归档时间: |
|
| 查看次数: |
4148 次 |
| 最近记录: |