React.js inline style best practices

2019-01-03 03:39发布

I'm aware that you can specify styles within React classes, like this:

var MyDiv = React.createClass({
  render: function() {
    var style = {
      color: 'white',
      fontSize: 200
    };

    return <div style={style}> Have a good and productive day! </div>;
  }
});

Should I be aiming to do all styling this way, and have no styles at all specified in my CSS file?

Or should I avoid inline styles completely?

It seems odd and messy to do a little bit of both - two places would need to be checked when tweaking styling.

14条回答
三岁会撩人
2楼-- · 2019-01-03 04:06

You can use StrCSS as well, it creates isolated classnames and much more! Example code would look like. You can (optional) install the VSCode extension from the Visual Studio Marketplace for syntax highlighting support!

source: https://github.com/jeffreylanters/strcss

import { Sheet } from "strcss";
import React, { Component } from "react";

const sheet = new Sheet(`
  map button
    color green
    color red !ios
    fontSize 16
  on hover
    opacity .5
  at mobile
    fontSize 10
`);

export class User extends Component {
  render() {
    return <div className={sheet.map.button}>
      {"Look mom, I'm green!
      Unless you're on iOS..."}
    </div>;
  }
}
查看更多
老娘就宠你
3楼-- · 2019-01-03 04:10

There aren't a lot of "Best Practices" yet. Those of us that are using inline-styles, for React components, are still very much experimenting.

There are a number of approaches that vary wildly: React inline-style lib comparison chart

All or nothing?

What we refer to as "style" actually includes quite a few concepts:

  • Layout — how an element/component looks in relationship to others
  • Appearance — the characteristics of an element/component
  • Behavior and state — how an element/component looks in a given state

Start with state-styles

React is already managing the state of your components, this makes styles of state and behavior a natural fit for colocation with your component logic.

Instead of building components to render with conditional state-classes, consider adding state-styles directly:

// Typical component with state-classes
<li 
 className={classnames({ 'todo-list__item': true, 'is-complete': item.complete })} />


// Using inline-styles for state
<li className='todo-list__item'
 style={(item.complete) ? styles.complete : {}} />

Note that we're using a class to style appearance but no longer using any .is- prefixed class for state and behavior.

We can use Object.assign (ES6) or _.extend (underscore/lodash) to add support for multiple states:

// Supporting multiple-states with inline-styles
<li 'todo-list__item'
 style={Object.assign({}, item.complete && styles.complete, item.due && styles.due )}>

Customization and reusability

Now that we're using Object.assign it becomes very simple to make our component reusable with different styles. If we want to override the default styles, we can do so at the call-site with props, like so: <TodoItem dueStyle={ fontWeight: "bold" } />. Implemented like this:

<li 'todo-list__item'
 style={Object.assign({},
         item.due && styles.due,
         item.due && this.props.dueStyles)}>

Layout

Personally, I don't see compelling reason to inline layout styles. There are a number of great CSS layout systems out there. I'd just use one.

That said, don't add layout styles directly to your component. Wrap your components with layout components. Here's an example.

// This couples your component to the layout system
// It reduces the reusability of your component
<UserBadge
 className="col-xs-12 col-sm-6 col-md-8"
 firstName="Michael"
 lastName="Chan" />

// This is much easier to maintain and change
<div class="col-xs-12 col-sm-6 col-md-8">
  <UserBadge
   firstName="Michael"
   lastName="Chan" />
</div>

For layout support, I often try to design components to be 100% width and height.

Appearance

This is the most contentious area of the "inline-style" debate. Ultimately, it's up to the component your designing and the comfort of your team with JavaScript.

One thing is certain, you'll need the assistance of a library. Browser-states (:hover, :focus), and media-queries are painful in raw React.

I like Radium because the syntax for those hard parts is designed to model that of SASS.

Code organization

Often you'll see a style object outside of the module. For a todo-list component, it might look something like this:

var styles = {
  root: {
    display: "block"
  },
  item: {
    color: "black"

    complete: {
      textDecoration: "line-through"
    },

    due: {
      color: "red"
    }
  },
}

getter functions

Adding a bunch of style logic to your template can get a little messy (as seen above). I like to create getter functions to compute styles:

React.createClass({
  getStyles: function () {
    return Object.assign(
      {},
      item.props.complete && styles.complete,
      item.props.due && styles.due,
      item.props.due && this.props.dueStyles
    );
  },

  render: function () {
    return <li style={this.getStyles()}>{this.props.item}</li>
  }
});

Further watching

I discussed all of these in more detail at React Europe earlier this year: Inline Styles and when it's best to 'just use CSS'.

I'm happy to help as you make new discoveries along the way :) Hit me up -> @chantastic

查看更多
男人必须洒脱
4楼-- · 2019-01-03 04:13

For some components, it is easier to use inline styles. Also, I find it easier and more concise (as I'm using Javascript and not CSS) to animate component styles.

For stand-alone components, I use the 'Spread Operator' or the '...'. For me, it's clear, beautiful, and works in a tight space. Here is a little loading animation I made to show it's benefits:

<div style={{...this.styles.container, ...this.state.opacity}}>
    <div style={{...this.state.colors[0], ...this.styles.block}}/>
    <div style={{...this.state.colors[1], ...this.styles.block}}/>
    <div style={{...this.state.colors[2], ...this.styles.block}}/>
    <div style={{...this.state.colors[7], ...this.styles.block}}/>
    <div style={{...this.styles.block}}/>
    <div style={{...this.state.colors[3], ...this.styles.block}}/>
    <div style={{...this.state.colors[6], ...this.styles.block}}/>
    <div style={{...this.state.colors[5], ...this.styles.block}}/>
    <div style={{...this.state.colors[4], ...this.styles.block}}/>
  </div>

    this.styles = {
  container: {
    'display': 'flex',
    'flexDirection': 'row',
    'justifyContent': 'center',
    'alignItems': 'center',
    'flexWrap': 'wrap',
    'width': 21,
    'height': 21,
    'borderRadius': '50%'
  },
  block: {
    'width': 7,
    'height': 7,
    'borderRadius': '50%',
  }
}
this.state = {
  colors: [
    { backgroundColor: 'red'},
    { backgroundColor: 'blue'},
    { backgroundColor: 'yellow'},
    { backgroundColor: 'green'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
  ],
  opacity: {
    'opacity': 0
  }
}

Then, in componentWillMount(), I set an interval like so...

this.interval = setInterval(() => {
  let colors = this.state.colors;
  let opacity = this.state.opacity;

  if(this.props.reverse) {
    let color = colors[colors.length-1];
    colors.pop();
    colors.unshift(color)
  } else {
    let color = colors[0];
    colors.shift();
    colors.push(color);
  }

  opacity['opacity'] < 1 ? opacity['opacity']+=0.06 : null;

  this.setState({colors, opacity});
}, this.speed);
查看更多
相关推荐>>
5楼-- · 2019-01-03 04:14

The style attribute in React expect the value to be an object, ie Key value pair.

style = {} will have another object inside it like {float:'right'} to make it work.

<span style={{float:'right'}}>{'Download Audit'}</span>

Hope this solves the problem

查看更多
ゆ 、 Hurt°
6楼-- · 2019-01-03 04:14

What I do is give each one of my reusable component a unique custom element name and then create a css file for that component, specifically, with all styling options for that component (and only for that component).

var MyDiv = React.createClass({
  render: function() {
    return <custom-component style={style}> Have a good and productive day! </custom-component>;
  }
});

And in file 'custom-component.css', every entry will start with the custom-component tag:

custom-component { 
   display: block; /* have it work as a div */
   color: 'white'; 
   fontSize: 200; 
} 
custom-component h1 { 
  font-size: 1.4em; 
}

That means you don't loose the critical notion of separating of concern. View vs style. If you share your component, it is easier for other to theme it to match the rest of their web page.

查看更多
放荡不羁爱自由
7楼-- · 2019-01-03 04:16

Depending on your configuration inline styling can offer you Hot reload. The webpage is immediately re-rendered every time the style changes. This helps me develop components quicker. Having said that, I am sure you can setup a Hot reload environment for CSS + SCSS.

查看更多
登录 后发表回答