Встроенные стили CSS в React:как реализовать a: hover?



мне очень нравится встроенный шаблон CSS в React и решил использовать его.



однако, вы не можете использовать :hover и подобные селекторы. Итак, каков наилучший способ реализации подсветки при наведении при использовании встроенных стилей CSS?



одно предложение от reactjs # - это Clickable компонент и использовать его как это:



<Clickable>
<Link />
</Clickable>


The Clickable есть hovered состояние и передает его в качестве реквизита для ссылки. Тем не менее,Clickable (путь I реализовано это) обертывает Link на div перед onMouseEnter и onMouseLeave к нему. Это делает вещи немного сложнее, хотя (например,span завернут в div ведет себя иначе, чем span).



есть ли более простой способ?

809   14  

14 ответов:

Я в такой же ситуации. Очень нравится шаблон сохранения стиля в компонентах, но состояния наведения кажутся последним препятствием.

то, что я сделал, это написать микс, который вы можете добавить в свой компонент, который нуждается в состояниях наведения. Этот миксин добавит новый hovered свойство состояния вашего компонента. Он будет установлен в true если пользователь нависает над главным узлом DOM компонента и устанавливает его обратно в false если пользователи покидают элемент.

теперь в вашей компонентной функции рендеринга вы можете сделать что-то вроде:

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

теперь каждый раз состояние hovered изменения состояния компонент будет перезаписан.

Я также создал репозиторий песочницы для этого, который я использую для тестирования некоторых из этих шаблонов сам. Проверьте это, если вы хотите увидеть пример моей реализации.

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

Я думаю, что onMouseEnter и onMouseLeave-это пути, но я не вижу необходимости в дополнительном компоненте оболочки. Вот как я это реализовал:

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>
    )
  }

затем вы можете использовать состояние наведения (true/false), чтобы изменить стиль ссылки.

вы можете использовать Radium-это инструмент с открытым исходным кодом для встроенных стилей с ReactJS. Он добавляет именно те селекторы, которые вам нужны. Очень популярный, проверьте его - Радий на НПМ

полная поддержка CSS-это именно та причина, по которой это огромное количество библиотек CSSinJS, чтобы сделать это эффективно, вам нужно создать фактический CSS, а не встроенные стили. Также встроенные стили намного медленнее реагируют в большей системе. Отказ от ответственности-я поддерживаю JSS.

составила Стиль -- частично -- из-за этой причины (другие-разногласия с реализацией других библиотек / синтаксиса и встроенных стилей отсутствие поддержки значений свойств префиксов). Считаю, что мы должны быть в состоянии просто написать CSS в JavaScript и иметь полностью автономные компоненты HTML-CSS-JS. С помощью строк шаблона ES5 / ES6 мы теперь можем, и это тоже может быть красиво! :)

npm install style-it --save

Функциональный Синтаксис (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;

синтаксис 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;

можно использовать css модули в качестве альтернативы, и дополнительно react-css-modules для сопоставления имен класса.

таким образом, вы можете импортировать свои стили следующим образом и использовать обычный css локально для ваших компонентов:

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);

здесь webpack css modules example

на Джонатан!--5-->, вот события для покрытия фокуса и активных состояний, а также использование onMouseOver вместо onMouseEnter поскольку последний не будет пузыриться, если у вас есть какие-либо дочерние элементы в целевом объекте, к которому применяется событие.

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>
    )
  }

оформить заказ Typestyle Если вы используете React with Typescript.

Ниже приведен пример кода для: hover

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>

в отношении styled-components и react-router v4 можно сделать так:

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

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

  &:hover {
    color: white;
  }
`

...
<Clickable><Link to="/somewhere">somewhere</Link></Clickable>

onmouseover модели и onMouseLeave при выполнении функция setState сначала казалось немного дополнительной нагрузки для меня - но как это, как реагировать работ, кажется, самый простой и наилучшим решением для меня.

рендеринг тематического css-сервера, например, также является хорошим решением и сохраняет компоненты react более чистыми.

Если вам не нужно добавлять динамические стили к элементам (например, для тематики ), вы не должны использовать встроенные стили вообще, но использовать классы css вместо.

Это традиционное правило html / css, чтобы сохранить html / JSX чистым и простым.

Я использую довольно Хак-иш решение для этого в одном из моих последних приложений, которое работает для моих целей, и я нахожу его быстрее, чем писать пользовательские функции настройки наведения в vanilla js (хотя, я признаю, может быть, не лучшая практика в большинстве сред..) Итак, если вам все еще интересно, вот.

Я создаю родительский элемент только ради удержания встроенных стилей javascript, а затем дочерний элемент с именем класса или идентификатором, на который будет цепляться моя таблица стилей css, и пишите стиль при наведении на выделенный файл CSS. Это работает, потому что более детализированный дочерний элемент получает встроенные стили js через наследование, но имеет свои стили наведения, переопределенные файлом css.

Итак, в основном, мой фактический файл css существует только для того, чтобы удерживать эффекты наведения, ничего больше. Это делает его довольно лаконичным и простым в управлении, а также позволяет мне выполнять тяжелую работу в моих встроенных стилях компонентов React.

вот пример:

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>

обратите внимание, что" дочерний "встроенный стиль не имеет набора свойств" цвет". Если бы это было так, это не сработало бы, потому что встроенный стиль будет иметь приоритет над моей таблицей стилей.

Это может быть хороший хак для того, чтобы иметь встроенный стиль внутри компонента react (а также использовать: hover CSS function):

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

простой способ-это использование тернарного оператора

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>
    )
  }

самым простым способом было бы просто добавить тег абзаца в ссылку и разобрать стиль на p. <Link to='/'><p style={{ color: '#000000' }}>Some text</p></Link>

Comments

    Ничего не найдено.