在同构 reactjs 中检测移动设备

Posted

技术标签:

【中文标题】在同构 reactjs 中检测移动设备【英文标题】:Detecting mobile in an isomorphic reactjs 【发布时间】:2016-05-05 12:03:00 【问题描述】:

我应该如何在我的 reactjs + express 中实现检测手机?我使用mobile-detect 来确定是否移动,但首先我使用const md = new MobileDetect(window.navigator.userAgent) 实现它,但我记得window 在服务器加载时不存在。 express 部分中的示例应该可以工作,因为这是我唯一可以访问req 的地方,但是我如何将它传递到我的反应应用程序中以供以后使用?

更新

// 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'
  , ...]

【问题讨论】:

您是如何在服务器端和客户端实现路由的?有很多方法可以解决这个问题,但您提供了有关您当前架构的更多信息。 我会更新我的配置问题,但请耐心等待,我不知道我是否发布了正确的配置。 【参考方案1】:

通过使我的路由模块成为一个接受用户代理的函数,我完全完成了您的要求。然后它只返回一个数组或嵌套路由。这是一个例子......

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
    
  
 

app.js

app.get('*', (req, res) => 
  match( routes: routes(req.headers['user-agent']), location: req.url , (err, redirectLocation, props) => 
    // continue as normal
  

client-render.js

ReactDOM.render(
  <Provider store=store>
    <Router onUpdate=() => scrollTop(); handleNotifs(store) history=browserHistory>
      routes(navigator.userAgent)
    </Router>
  </Provider>,
  document.getElementById('app')
);

附带说明一下,使用这种方法,我们还可以将 auth cookie 传递给路由,因此如果路由落后于登录,onEnter 方法可以重定向。

希望这会有所帮助! BTW React-Router 是最好的!!我在纽约见到了创作者,他们是一流的。

【讨论】:

再想一想,这只会解决基于移动设备的路线选择...您想简单地将isMoble 从服务器渲染传递到应用程序?在renderToString 期间,您始终可以将其作为道具传递给组件,并在客户端渲染中也执行相同的操作。 这对我有用。我为移动和桌面网站生成了不同的块。使用它,我能够在移动设备中仅动态加载移动组件,而在桌面设备中仅动态加载桌面组件。

以上是关于在同构 reactjs 中检测移动设备的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS 应用程序无法在移动设备上运行

ReactJS:如何确定应用程序是在移动浏览器还是桌面浏览器上查看

检测移动设备的最佳方法是啥?

PHP 在移动设备中检测设备

在移动设备上,ReactJS 背景视频(样式化的组件)会跳转到全屏,您必须将其滑开才能将其移除。你如何解决这个问题?

Paypal 在结帐时无法检测到移动设备