Styles css en ligne dans React: comment mettre en œuvre un: hover?

j'aime bien le inline CSS modèle de Réagir et décidé de l'utiliser.

cependant, vous ne pouvez pas utiliser les sélecteurs :hover et similaires. Alors, quelle est la meilleure façon de mettre en œuvre highlight-on-hover tout en utilisant les styles css inline?

une suggestion de #reactjs est d'avoir un composant Clickable et de l'utiliser comme ceci:

<Clickable>
    <Link />
</Clickable>

le Clickable a un hovered état et le passe comme un accessoire pour le lien. Cependant ,le Clickable (la façon dont je l'ai mis en œuvre) enveloppe le Link dans un div de sorte qu'il peut fixer onMouseEnter et onMouseLeave à elle. Cela rend les choses un peu compliquées cependant (par exemple span enveloppé dans un div se comporte différemment de span ).

y a-t-il un moyen plus simple?

99
demandé sur Elias Ojala 2015-02-06 14:54:38

14 réponses

je suis dans la même situation. Vraiment comme le modèle de garder le style dans les composantes, mais les états stationnaire semble que le dernier obstacle.

ce que j'ai fait était d'écrire un mixin que vous pouvez ajouter à votre composant qui a besoin d'états de vol stationnaire. Ce mixin ajoutera une nouvelle propriété hovered à l'état de votre composant. Il sera défini à true si l'utilisateur survole le noeud DOM principal du composant et le renvoie à false si l'utilisateur quitte élément.

maintenant dans votre fonction de rendu de Composant vous pouvez faire quelque chose comme:

<button style={m(
        this.styles.container,
        this.state.hovered && this.styles.hover,
      )}>{this.props.children}</button>

maintenant à chaque fois que l'état de l'état hovered change le composant va se dérégler.

j'ai aussi créé un bac à sable repo pour cela que j'utilise pour tester certains de ces modèles moi-même. Regardez si vous voulez voir un exemple de mon implémentation.

https://github.com/Sitebase/cssinjs/tree/feature-interaction-mixin

28
répondu Wim Mostmans 2015-02-06 15:41:47

je pense qu'onMouseEnter et onMouseLeave sont les chemins à suivre, mais je ne vois pas la nécessité d'un composant d'enrubannage supplémentaire. Voici comment je l'ai mis en œuvre:

var Link = React.createClass({
  getInitialState: function(){
    return {hover: false}
  },
  toggleHover: function(){
    this.setState({hover: !this.state.hover})
  },
  render: function() {
    var linkStyle;
    if (this.state.hover) {
      linkStyle = {backgroundColor: 'red'}
    } else {
      linkStyle = {backgroundColor: 'blue'}
    }
    return(
      <div>
        <a style={linkStyle} onMouseEnter={this.toggleHover} onMouseLeave={this.toggleHover}>Link</a>
      </div>
    )
  }

Vous pouvez ensuite utiliser l'état de pointage (true/false) pour modifier le style du lien.

67
répondu Jonathan 2016-03-17 20:47:24

vous pouvez utiliser Radium - c'est un outil open source pour les styles en ligne avec ReactJS. Il ajoute exactement les sélecteurs dont vous avez besoin. Très populaire, allez voir - Radium sur npm

23
répondu Gyro 2015-07-06 20:04:07

support CSS complet est exactement la raison de cette énorme quantité de bibliothèques CSSinJS, pour le faire efficacement, vous devez générer des CSS réels, pas des styles inline. Aussi les styles en ligne sont beaucoup plus lents dans react dans un système plus grand. Avertissement - je maintenir JSS .

6
répondu Oleg Isonen 2017-06-20 09:53:58

Made Style It -- en partie -- pour cette raison (d'autres étant des désaccords avec la mise en œuvre d'autres libs / syntaxe et stylings en ligne manque de support pour le préfixe des valeurs de propriété). Nous croyons que nous devrions être en mesure d'écrire simplement CSS en JavaScript et avoir des composants entièrement autonomes HTML-CSS-JS. Avec ES5 / ES6 template strings, nous pouvons maintenant le faire et il peut être joli aussi! :)

npm install style-it --save

Syntaxe fonctionnelle ( JSFIDDLE )

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return Style.it(`
      .intro:hover {
        color: red;
      }
    `,
      <p className="intro">CSS-in-JS made simple -- just Style It.</p>
    );
  }
}

export default Intro;

syntaxe JSX ( JSFIDDLE )

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return (
      <Style>
      {`
        .intro:hover {
          color: red;
        }
      `}

        <p className="intro">CSS-in-JS made simple -- just Style It.</p>
      </Style>
    );
  }
}

export default Intro;
6
répondu Joshua Robinson 2018-03-16 02:05:57

vous pouvez utiliser CSS modules comme alternative, et en outre react-CSS-modules pour la cartographie des noms de classe.

de cette façon, vous pouvez importer vos styles comme suit et utiliser CSS normales scoped localement à vos composants:

import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './table.css';

class Table extends React.Component {
    render () {
        return <div styleName='table'>
            <div styleName='row'>
                <div styleName='cell'>A0</div>
                <div styleName='cell'>B0</div>
            </div>
        </div>;
    }
}

export default CSSModules(Table, styles);

voici un webpack CSS modules exemple

3
répondu steven iseki 2015-11-27 04:14:38

ajoutant à la réponse de Jonathan , voici les événements pour couvrir le focus et les états actifs, et un en utilisant onMouseOver au lieu de onMouseEnter puisque ce dernier ne fera pas de bulle si vous avez des éléments enfants dans la cible à laquelle l'événement est appliqué.

var Link = React.createClass({

  getInitialState: function(){
    return {hover: false, active: false, focus: false}
  },

  toggleHover: function(){
    this.setState({hover: !this.state.hover})
  },

  toggleActive: function(){
    this.setState({active: !this.state.active})
  },

  toggleFocus: function(){
    this.setState({focus: !this.state.focus})
  },

  render: function() {
    var linkStyle;
    if (this.state.hover) {
      linkStyle = {backgroundColor: 'red'}
    } else if (this.state.active) {
      linkStyle = {backgroundColor: 'blue'}
    } else if (this.state.focus) {
      linkStyle = {backgroundColor: 'purple'}
    } 

    return(
      <div>
        <a style={linkStyle} 
          onMouseOver={this.toggleHover} 
          onMouseOut={this.toggleHover} 
          onMouseUp={this.toggleActive} 
          onMouseDown={this.toggleActive} 
          onFocus={this.toggleFocus}> 
          Link 
        </a>
      </div>
    )
  }
3
répondu Rachel Cantor 2017-09-08 16:14:07

Checkout Typestyle si vous utilisez React with Typescript.

ci-dessous est un exemple de code pour:"

import {style} from "typestyle";

/** convert a style object to a CSS class name */
const niceColors = style({
  transition: 'color .2s',
  color: 'blue',
  $nest: {
    '&:hover': {
      color: 'red'
    }
  }
});

<h1 className={niceColors}>Hello world</h1>
2
répondu paibamboo 2017-01-24 02:44:45

En ce qui concerne style-composants et réagissent-routeur v4 vous pouvez faire ceci:

import {NavLink} from 'react-router-dom'

const Link = styled(NavLink)`     
  background: blue;

  &:hover {
    color: white;
  }
`

...
<Clickable><Link to="/somewhere">somewhere</Link></Clickable>
2
répondu Isaac Pak 2017-10-29 18:55:24

onMouseOver et onMouseLeave avec setState au début m'ont semblé un peu au - dessus de la tête- mais comme c'est ainsi que react fonctionne, il semble que la solution la plus facile et la plus propre pour moi.

rendre un theming CSS serverside par exemple, est également une bonne solution et maintient les composants réagir plus propre.

si vous n'avez pas à ajouter de styles dynamiques aux éléments ( par exemple pour un theming ) , vous ne devez pas utiliser de styles inline mais utiliser des classes css plutôt.

c'est une règle html/css traditionnelle pour garder html / JSX propre et simple.

2
répondu lukas gurschler 2018-06-27 12:08:17

j'utilise une solution assez hack-ish pour cela dans une de mes récentes applications qui fonctionne à mes fins, et je le trouve plus rapide que d'écrire des fonctions personnalisées de réglages de vol stationnaire dans vanilla js (bien que, je reconnais, peut-être pas une meilleure pratique dans la plupart des environnements.. Donc, au cas où tu serais toujours intéressé, voilà.

je crée un élément parent juste pour le plaisir de tenir les styles javascript en ligne, puis un enfant avec un nom de classe ou un id que ma feuille de style css va verrouillez et écrivez le style hover dans mon fichier CSS dédié. Cela fonctionne parce que l'élément enfant plus granulaire reçoit les styles js inline via l'héritage, mais a ses styles hover dépassés par le fichier css.

donc en gros, mon fichier CSS existe dans le seul but de maintenir des effets de vol stationnaire, rien d'autre. Cela le rend assez concis et facile à gérer, et me permet de faire le levage lourd dans mes styles de composants à réaction en ligne.

Voici un exemple:

const styles = {
  container: {
    height: '3em',
    backgroundColor: 'white',
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'stretch',
    justifyContent: 'flex-start',
    borderBottom: '1px solid gainsboro',
  },
  parent: {
    display: 'flex',
    flex: 1,
    flexDirection: 'row',
    alignItems: 'stretch',
    justifyContent: 'flex-start',
    color: 'darkgrey',
  },
  child: {
    width: '6em',
    textAlign: 'center',
    verticalAlign: 'middle',
    lineHeight: '3em',
  },
};

var NavBar = (props) => {
  const menuOptions = ['home', 'blog', 'projects', 'about'];

  return (
    <div style={styles.container}>
      <div style={styles.parent}>
        {menuOptions.map((page) => <div className={'navBarOption'} style={styles.child} key={page}>{page}</div> )}
      </div>
    </div>
  );
};


ReactDOM.render(
  <NavBar/>,
  document.getElementById('app')
);
.navBarOption:hover {
  color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>

notez que le style inline" child "n'a pas de propriété" color". Si c'était le cas, cela ne fonctionnerait pas parce que le style inline aurait la priorité sur ma feuille de style.

0
répondu witygass 2017-02-26 21:15:33

cela peut être un bon hack pour avoir le style inline à l'intérieur d'un composant react (et aussi en utilisant :hover CSS function):

... <style> {`.galleryThumbnail.selected:hover{outline:2px solid #00c6af}`} </style> ...

0
répondu tomericco 2018-01-07 10:33:25

la manière simple est d'utiliser l'opérateur ternaire

var Link = React.createClass({
  getInitialState: function(){
    return {hover: false}
  },
  toggleHover: function(){
    this.setState({hover: !this.state.hover})
  },
  render: function() {
    var linkStyle;
    if (this.state.hover) {
      linkStyle = {backgroundColor: 'red'}
    } else {
      linkStyle = {backgroundColor: 'blue'}
    }
    return(
      <div>
        <a style={this.state.hover ? {"backgroundColor": 'red'}: {"backgroundColor": 'blue'}} onMouseEnter={this.toggleHover} onMouseLeave={this.toggleHover}>Link</a>
      </div>
    )
  }
0
répondu Think-Twice 2018-09-28 11:07:09

la façon la plus simple serait simplement d'ajouter une balise de paragraphe dans le style lien et analyse à la P. <Link to='/'><p style={{ color: '#000000' }}>Some text</p></Link>

-1
répondu LiJonas 2017-07-21 14:54:47