【问题标题】:React Starter Kit and Material UI: userAgent should be supplied in the muiTheme context for server-side renderingReact Starter Kit 和 Material UI:应该在 muiTheme 上下文中提供 userAgent 以进行服务器端渲染
【发布时间】:2016-02-18 12:08:14
【问题描述】:

使用React Starter Kit,我添加Material UI如下:

npm install material-ui --save

以及以下对组件的导入:

import RaisedButton from 'material-ui/lib/raised-button';

和:

<RaisedButton label="Default" />

我收到以下错误:

警告:Material-UI:应在 muiTheme 上下文中提供 userAgent 以进行服务器端渲染。

根据 Material UI 的 documentation,它说我需要解决三件事:

  1. 自动前缀和用户代理
  2. process.env.NODE_ENV

我应该输入什么代码以及确切的位置,特别是使用 React Starter Kit?

附: this solution 对我不起作用:-/

【问题讨论】:

    标签: reactjs isomorphic-javascript material-ui react-starter-kit


    【解决方案1】:

    在使用 Material-UI 和服务器渲染时,我们必须为服务器和客户端使用相同的环境。这有两个技术含义。

    正如您在 MaterialUI documentation 页面上看到的那样

    您需要为服务器和浏览器上下文提供相同的用户代理,正如您在文档中看到的那样,但是,我强烈不建议您提供“全部”用户代理,因为您将提供大量不必要的代码给您的最终用户。

    相反,您可以轻松地关注 MaterialUI 文档并传递 http 请求标头中包含的用户代理值。

    使用 express 或 koa 服务器

    global.navigator = global.navigator || {};
    global.navigator.userAgent = req.headers['user-agent'] || 'all';
    

    我刚刚在src/server.js 中检查了it has been added to the ReactStarterKit(我自己没有测试过)

    global.navigator = global.navigator || {};
    global.navigator.userAgent = global.navigator.userAgent || 'all';
    

    【讨论】:

    • 这绝对不会在服务器端正常工作,因为节点可以同时处理多个请求(针对不同的浏览器),从而将global.navigator 的全局值覆盖为不正确的中间周期。
    【解决方案2】:

    这应该可以解决它

    import themeDecorator from 'material-ui/lib/styles/theme-decorator';
    import RaisedButton from 'material-ui/lib/raised-button';
    import getMuiTheme from 'material-ui/lib/styles/getMuiTheme';
    
    class MyComponent extends Component {
     render() {
       return (<RaisedButton label="Default" />);
      }
    }
    
    export default themeDecorator(getMuiTheme(null, { userAgent: 'all' }))(MyComponent);
    

    【讨论】:

    • 有人告诉我改用 MuiThemeProvider,因为 themeDecorator 已被弃用。
    • 我同意你应该使用MuiThemeProvidergetMuiTheme(null, { userAgent: 'all' }) 仍然有效,在我看来它比声明全局变量更优雅。
    • 嗨@RomanStarkov 和GiladArtzi,我想你可以做到this way
    【解决方案3】:

    这对我有用。将此添加到server.js

    global.navigator = { userAgent: 'all' };
    

    然后验证您是否看到使用了多个供应商前缀,如此屏幕截图中显示的 -webkit-ms 都在使用:

    【讨论】:

    • 此解决方案将导致无效校验和display:-webkit-box,-moz-box,-ms-flexbox... 请小心,现在它会破坏您的客户端行为以支持信任 userAgent 的内联样式前缀
    • 是的@IdanGozlan,我认为this solution 更好。
    【解决方案4】:

    尝试在 server.js 文件(Node.js 入口点)的顶部添加 global.navigator = { userAgent: 'all' };

    【讨论】:

    • 谢谢。我尝试在server.js 的最顶部(第一行)添加它,并在所有导入之后再次添加 - 仍然收到相同的警告。
    • 我查看了代码并注意到我们需要global.navigator.userAgent = 'all' 而不是global.navigator = ''global.navigator = 'all'。将在 GitHub 讨论中提到这一点。
    【解决方案5】:

    对我来说有效(也是最干净)的解决方案简短而简单:

    getMuiTheme({userAgent: (typeof navigator !== 'undefined' && navigator.userAgent) || 'all' })
    

    示例(来自我的测试应用):

    <MuiThemeProvider muiTheme={getMuiTheme({userAgent: (typeof navigator !== 'undefined' && navigator.userAgent) || 'all' })}>
        <Provider store={store}>
            <MyApplication/>
        </Provider>
    </MuiThemeProvider>
    

    【讨论】:

    • 这个解决方案不完整,抛出ReferenceError: navigator is not defined
    • 错了。 ReferenceError: navigator is not defined
    • 嗨@ThomasModeneis 和格林,我认为这个解决方案是正确的并且也有效:stackoverflow.com/a/43958563/6226738
    • 它应该是global.navigator
    【解决方案6】:

    如果你使用 KoaJS 服务器,你应该安装 koa-useragent 然后在服务器端渲染之前使用它:

      global.navigator = global.navigator || {};
      global.navigator.userAgent = this.state.userAgent.source || 'all';
    

    它对我有用!

    【讨论】:

      猜你喜欢
      • 2018-05-18
      • 2020-10-01
      • 2017-05-26
      • 2019-02-24
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      • 2020-01-27
      • 2017-08-13
      相关资源
      最近更新 更多