简体   繁体   English

渲染需要服务器样式的React组件

[英]Render React components which require styles on server

I have React.js components that require styles inside: 我有React.js组件,里面需要样式:

import './styles.css
import React from 'react';

export default class Basket extends React.Component {
    ...
}

Now I want to make my app isomorphic and prerender it on server.. 现在我想让我的应用程序同构并在服务器上预呈现它..

There's no surprise that Babel starts to complain about css files: Babel开始抱怨css文件就不足为奇了:

SyntaxError: /Users/dmitri/github/app/src/client/pages/styles.css: Unexpected token (3:5)
  2 |
> 3 | body {
    |      ^
  4 |     background-color: #ddd;
  5 | }
  6 |

How to make it work? 如何使它工作? There's similar discussion on node-jsx - https://github.com/petehunt/node-jsx/issues/29 node-jsx上有类似的讨论 - https://github.com/petehunt/node-jsx/issues/29

Should I add if (browser) statements for this imports? 我应该为此导入添加if (browser)语句吗?

It's a bit of a different approach, but check out Radium . 这是一个不同的方法,但检查 You can declare your styles as JS objects, so the server won't have to know or care about what css is. 您可以将样式声明为JS对象,因此服务器不必知道或关心css是什么。

Example from the Radium page: Radium页面的示例:

 var React = require('react'); var Radium = require('radium'); var color = require('color'); var Button = React.createClass(Radium.wrap({ displayName: "Button", propTypes: { kind: React.PropTypes.oneOf(['primary', 'warning']).isRequired }, render: function () { // Radium extends the style attribute to accept an array. It will merge // the styles in order. We use this feature here to apply the primary // or warning styles depending on the value of the `kind` prop. Since its // all just JavaScript, you can use whatever logic you want to decide which // styles are applied (props, state, context, etc). return ( <button style={[ styles.base, styles[this.props.kind] ]}> {this.props.children} </button> ); } })); // You can create your style objects dynamically or share them for // every instance of the component. var styles = { base: { padding: '1.5em 2em', border: 0, borderRadius: 4, color: '#fff', cursor: 'pointer', fontSize: 16, fontWeight: 700, // Adding interactive state couldn't be easier! Add a special key to your // style object (:hover, :focus, :active, or @media) with the additional rules. ':hover': { background: color('#0074d9').lighten(0.2).hexString() }, // If you specify more than one, later ones will override earlier ones. ':focus': { boxShadow: '0 0 0 3px #eee, 0 0 0 6px #0074D9', outline: 'none' }, }, primary: { background: '#0074D9' }, warning: { background: '#FF4136' } }; 

Remember, if you're not a fan of inline css, you could always define your styles in a separate JS and import them. 请记住,如果您不是内联css的粉丝,您可以随时在单独的JS中定义样式并导入它们。

I have exactly the same needs as you. 我和你有完全相同的需求。 I use webpack for package my app. 我使用webpack打包我的应用程序。 In webpack, you can define severals variables like this: 在webpack中,您可以定义几个变量,如下所示:

var define = new webpack.DefinePlugin({
    "process.env": {
        BROWSER: JSON.stringify(true)
    }
});

In my jsx file: 在我的jsx文件中:

if (process.env.BROWSER) {
    require('my-css');
}

I think, there are other way to manage css. 我认为,还有其他方法来管理CSS。 This is one way to do. 这是一种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM