React의 인라인 CSS 스타일 : hover를 구현하는 방법은 무엇입니까?


178

나는 React에서 인라인 CSS 패턴을 좋아하고 그것을 사용하기로 결정했습니다.

그러나 :hover유사한 선택기를 사용할 수 없습니다 . 인라인 CSS 스타일을 사용하는 동안 마우스로 강조 표시를 구현하는 가장 좋은 방법은 무엇입니까?

#reactjs의 제안 중 하나는 Clickable구성 요소 를 가지고 다음 과 같이 사용하는 것입니다.

<Clickable>
    <Link />
</Clickable>

Clickablehovered상태 및 링크에 소품으로 전달합니다. 그러나, Clickable(그런데 나는 그것을 구현)는 래핑 LinkA의 div가 설정할 수 있도록 onMouseEnter하고 onMouseLeave그것. 그래도 상황이 약간 복잡해집니다 (예 :에 span래핑되어있는 div것과 다르게 동작 함 span).

더 간단한 방법이 있습니까?


1
인라인 스타일의 : hover etc 선택기를 시뮬레이션하는 유일한 방법은 onMouseEnterand 를 사용하는 것 onMouseLeave입니다. 그것의 정확한 구현에 관해서는 전적으로 당신에게 달려 있습니다. 특정 예제를 보려면 <Clickable/>래퍼를 span?
Chris Houghton

3
혹시 그렇지 않으면 당신은 라듐 시도 할 수 ServerRender하려면 내가 ExtractText 웹팩 플러그인과 함께 외부 스타일 시트를 사용하는 것이 좋습니다 것, 이것은 더 이상 실행에 도움이 될 것입니다 github.com/FormidableLabs/radium을
abhirathore2006

현재 스타일 이 지정된 구성 요소 는 css / scss의 모든 가능성을 반응으로 시뮬레이션하는 최상의 솔루션입니다.
Ahmad Behzadi

답변:


43

나는 같은 상황에 처해 있습니다. 구성 요소에 스타일을 유지하는 패턴과 같지만 호버 상태는 마지막 장애물처럼 보입니다.

내가 한 것은 호버 상태가 필요한 구성 요소에 추가 할 수있는 믹스 인을 작성하는 것이 었습니다. 이 믹스 인은 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


3
장기 실행에 적합한 솔루션이 아니라면 Radium이 더 나은 선택이거나 외부 스타일 시트를 사용하는 것입니다.
abhirathore2006

16
@ abhirathore2006 Radium도 같은 방식으로 작동하며 문제는 외부 스타일 시트를 사용하지 않고이를 수행하는 방법입니다.
Charlie Martin

바닐라 스프레드 연산자를 사용하는 것이 더 합리적이지 않습니까?
PAT-O-MATION 5

102

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)를 사용하여 링크 스타일을 변경할 수 있습니다.


1
이 커버 것 같다 :hover하지만:focus
아담 터틀

3
@AdamTuttle react에 onFocus이벤트가 있습니다. 당신은 같은 일을 할 수 있도록 :focus:hover, 대신에 필요로 제외시켰다 onMouseEnter그리고 onMouseLeave당신은 단지 필요onFocus
조나단

7
이 메소드는 기본 스레드에서 강제로 실행되는 반면 일반적인 CSS 이벤트는 훨씬 더 효율적으로 처리됩니다.
Hampus Ahlgren 2016

54

파티에 늦었지만 해결책이 있습니다. "&"를 사용하여 자식 등의 스타일을 정의 할 수 있습니다.

day: {
    display: "flex",
    flex: "1",
    justifyContent: "center",
    alignItems: "center",
    width: "50px",
    height: "50px",
    transition: "all 0.2s",
    borderLeft: "solid 1px #cccccc",

    "&:hover": {
      background: "#efefef"
    },
    "&:last-child": {
      borderRight: "solid 1px #cccccc"
    }
},

1
이것은 해결책이 아니며, 문제는 별도의 스타일 시트가 아닌 INLINE CSS로 처리하는 방법이었습니다.
Emmy

35
야, 좀 더 가까이 봐. 이것은 인라인 스타일입니다.
Jarosław Wlazło

15
React에서는 작동하지 않습니다. 스타일 구성 요소와 같은 추가 라이브러리가 필요합니다.
GG.

3
인라인 스타일에서는 작동하지 않습니다.이 예제에서는 혼동이 발생합니다. 실제로 작동하는 경우 전체 구성 요소로 더 나은 예를 제공하십시오.
Alexandre

2
우수한! 매력처럼 작동합니다!
Fyodor

26

Radium을 사용할 수 있습니다-ReactJS와 함께 인라인 스타일을위한 오픈 소스 도구입니다. 필요한 선택기를 정확하게 추가합니다. 매우 인기있는, 확인하십시오 -npm의 라듐


방금이 게시물을 보았습니다. 다음 상황에서 Radium을 어떻게 구현 하시겠습니까? module.exports = React.createClass({ displayName: 'App',})

1
@Rkhayat 당신은 그것을 감싸 module.exports = Radium(React.createClass({ displayName: 'App',}))거나 클래스를 값에 할당 @Radium하고 문서에 언급 한 것처럼 github.com/FormidableLabs/radium#usage
pbojinov

CSS라고 불리는이 위대한 것도 있습니다.)
Pixelomo

11

완전한 CSS 지원은이 방대한 양의 CSSinJS 라이브러리를 정확하게 수행하는 이유입니다.이를 효율적으로 수행하려면 인라인 스타일이 아닌 실제 CSS를 생성해야합니다. 또한 더 큰 시스템에서는 인라인 스타일이 반응 속도가 훨씬 느립니다. 면책 조항 -JSS를 유지 관리 합니다.


9

Made Style 그것은 부분적으로이 이유로 인해 (다른 라이브러리 / 구문의 구현에 동의하지 않는 것과 인라인 스타일링은 접두사 속성 값에 대한 지원이 없음) 때문입니다. JavaScript로 간단하게 CSS를 작성할 수 있고 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;

JSX 구문 예제에서 JSFiddle 링크에 올바른 코드가 있지만 여기에 표시된 예제에는 닫는 스타일 태그 뒤에 닫는 괄호가 누락되어 있으며 괄호가 누락되어 들여 쓰기가 꺼져있을 수 있습니다.
bradleygsmith

8

Jonathan의 답변덧붙여서 여기 초점과 활성 상태를 다루는 이벤트가 있습니다. 이벤트에 적용되는 대상 내에 자식 요소가 있으면 후자가 버블 링되지 않기 때문에 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>
    )
  }

7

여기 React Hooks를 사용하는 솔루션이 있습니다. 스프레드 연산자와 삼항 연산자를 결합합니다.

style.js

export default {
  normal:{
    background: 'purple',
    color: '#ffffff'
  },
  hover: {
    background: 'red'
  }
}

Button.js

import React, {useState} from 'react';
import style from './style.js'

function Button(){

  const [hover, setHover] = useState(false);

  return(
    <button
      onMouseEnter={()=>{
        setHover(true);
      }}
      onMouseLeave={()=>{
        setHover(false);
      }}
      style={{
        ...style.normal,
        ...(hover ? style.hover : null)
      }}>

        MyButtonText

    </button>
  )
}


6

반응 구성 요소 내부에 인라인 스타일이 있고 (: hover CSS 함수 사용) 좋은 해킹이 될 수 있습니다.

...

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

...

5

Typescript와 함께 React를 사용하는 경우 Checkout Typestyle .

아래는 : 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>

4

대안으로 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 모듈 예제입니다


참고 : Meteor를 사용하는 경우 github.com/nathantreid/meteor-css-modules 패키지를 확인하십시오 . 나는 지금까지 큰 성공을 거두어 그것을 사용하고 있습니다.
Spiralis

이것은 구성 요소의 반응 스타일을 지정하는 좋은 방법이지만 인라인 스타일을 완전히 제어 할 수는 없습니다. 예를 들어 :hoverRadium 또는 다른 onMouseOver기반 솔루션을 사용하는 것처럼 런타임에 스타일을 변경할 수 없습니다.
Charlie Martin

4

처음에 setState가있는 onMouseOver 및 onMouseLeave는 약간의 오버 헤드처럼 보였습니다. 그러나 이것이 반응하는 방식이므로 가장 쉽고 깨끗한 솔루션입니다.

예를 들어 테마 CSS 서버 측을 렌더링하는 것도 좋은 솔루션이며 반응 구성 요소를보다 깨끗하게 유지합니다.

요소에 동적 스타일을 추가 할 필요가없는 경우 (예 : 테마) 인라인 스타일을 전혀 사용하지 말고 대신 CSS 클래스를 사용해야합니다.

이것은 HTML / JSX를 깨끗하고 간단하게 유지하는 전통적인 html / css 규칙입니다.


4

간단한 방법은 삼항 연산자를 사용하는 것입니다

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

1

후크를 사용하여 :

const useFade = () => {
  const [ fade, setFade ] = useState(false);

  const onMouseEnter = () => {
    setFade(true);
  };

  const onMouseLeave = () => {
    setFade(false);
  };

  const fadeStyle = !fade ? {
    opacity: 1, transition: 'all .2s ease-in-out',
  } : {
    opacity: .5, transition: 'all .2s ease-in-out',
  };

  return { fadeStyle, onMouseEnter, onMouseLeave };
};

const ListItem = ({ style }) => {
  const { fadeStyle, ...fadeProps } = useFade();

  return (
    <Paper
      style={{...fadeStyle, ...style}}
      {...fadeProps}
    >
      {...}
    </Paper>
  );
};

0

내 목적에 맞는 최근 응용 프로그램 중 하나 에서이 작업에 꽤 해킹 된 솔루션을 사용하고 있으며 바닐라 js에서 사용자 지정 호버 설정 기능을 작성하는 것보다 빠릅니다 (그러나 대부분의 환경에서 모범 사례는 아니지만 ..) 그래도 여전히 관심이 있다면 여기로갑니다.

인라인 자바 스크립트 스타일을 유지하기 위해 부모 요소를 만든 다음 CSS 스타일 시트가 고정되어 호버 스타일을 전용 CSS 파일에 쓰는 className 또는 id를 가진 자식을 만듭니다. 보다 세분화 된 자식 요소는 상속을 통해 인라인 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>

"자식"인라인 스타일에는 "색상"속성이 설정되어 있지 않습니다. 그렇다면 인라인 스타일이 내 스타일 시트보다 우선하기 때문에 작동하지 않습니다.


0

이것이 대답인지 100 % 확실하지 않지만 색상과 이미지를 인라인으로 CSS : hover 효과를 시뮬레이션하는 데 사용하는 트릭입니다.

`This works best with an image`

class TestHover extends React.PureComponent {
render() {
const landingImage = {     
"backgroundImage": "url(https://i.dailymail.co.uk/i/pix/2015/09/01/18/2BE1E88B00000578-3218613-image-m-5_1441127035222.jpg)",
"BackgroundColor": "Red", `this can be any color`
"minHeight": "100%",
"backgroundAttachment": "fixed",
"backgroundPosition": "center",
"backgroundRepeat": "no-repeat",
"backgroundSize": "cover", 
"opacity": "0.8", `the hove trick is here in the opcaity slightly see through gives the effect when the background color changes`
    }

  return (
    <aside className="menu">
        <div className="menu-item">
          <div style={landingImage}>SOME TEXT</div>
        </div>
    </aside>
      ); 
  }
}
ReactDOM.render(
    <TestHover />,
  document.getElementById("root")
);

CSS :

.menu {
top: 2.70em;
bottom: 0px;
width: 100%;
position: absolute;
}

.menu-item {
cursor: pointer;
height: 100%;
font-size: 2em;
line-height: 1.3em;
color: #000;
font-family: "Poppins";
font-style: italic;
font-weight: 800;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
}

호버 전에

.menu-item:nth-child(1) {
color: white;
background-color: #001b37;
} 

호버

.menu-item:nth-child(1):hover {
color: green;
background-color: white;
}

예 : https://codepen.io/roryfn/pen/dxyYqj?editors=0011


0
<Hoverable hoverStyle={styles.linkHover}>
  <a href="https://example.com" style={styles.link}>
    Go
  </a>
</Hoverable>

Hoverable은 다음과 같이 정의됩니다.

function Hoverable(props) {
  const [hover, setHover] = useState(false);

  const child = Children.only(props.children);

  const onHoverChange = useCallback(
    e => {
      const name = e.type === "mouseenter" ? "onMouseEnter" : "onMouseLeave";
      setHover(!hover);
      if (child.props[name]) {
        child.props[name](e);
      }
    },
    [setHover, hover, child]
  );

  return React.cloneElement(child, {
    onMouseEnter: onHoverChange,
    onMouseLeave: onHoverChange,
    style: Object.assign({}, child.props.style, hover ? props.hoverStyle : {})
  });
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.