Programming

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

procodes 2020. 6. 19. 22:02
반응형

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


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

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

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

<Clickable>
    <Link />
</Clickable>

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

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


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

내가 한 것은 호버 상태가 필요한 구성 요소에 추가 할 수있는 믹스 인을 작성하는 것이 었습니다. 이 믹스 인은 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와 함께 인라인 스타일을위한 오픈 소스 도구입니다. 필요한 선택기를 정확하게 추가합니다. 매우 인기있는, 확인하십시오 -npm의 라듐


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


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;

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

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"
    }
},

스타일이 지정된 구성 요소반응 라우터 v4관련하여 다음을 수행 할 수 있습니다.

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

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

  &:hover {
    color: white;
  }
`

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

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>

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

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


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

...

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

...


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

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

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

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


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

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

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

내 목적에 맞는 최근 응용 프로그램 중 하나 에서이 작업에 꽤 해킹 된 솔루션을 사용하고 있으며 바닐라 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>

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


후크를 사용하여 :

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

이것이 대답인지 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

참고 URL : https://stackoverflow.com/questions/28365233/inline-css-styles-in-react-how-to-implement-ahover

반응형