ReactJS에서 어떻게 Hover합니까? -빠른 마우스 오버 중에 onMouseLeave가 등록되지 않았습니다.


101

인라인 스타일링을 할 때 ReactJS에서 hover 이벤트 또는 활성 이벤트를 어떻게 얻을 수 있습니까?

나는 onMouseEnter, onMouseLeave 접근 방식이 버그가 있음을 알았으므로 다른 방법이 있기를 바랍니다.

특히 구성 요소 위로 마우스를 빠르게 가져 가면 onMouseEnter 이벤트 만 등록됩니다. onMouseLeave는 실행되지 않으므로 상태를 업데이트 할 수 없습니다. ": active"css 가상 클래스를 모방하려고하면 똑같은 것을 알아 차 렸습니다. 정말 빠르게 클릭하면 onMouseDown 이벤트 만 등록됩니다. onMouseUp 이벤트는 무시됩니다 ... 구성 요소는 활성 상태로 유지됩니다.

다음은 문제를 보여주는 JSFiddle입니다 : https://jsfiddle.net/y9swecyu/5/

문제가있는 JSFiddle 비디오 : https://vid.me/ZJEO

코드:

var Hover = React.createClass({
    getInitialState: function() {
        return {
            hover: false
        };
    },
    onMouseEnterHandler: function() {
        this.setState({
            hover: true
        });
        console.log('enter');
    },
    onMouseLeaveHandler: function() {
        this.setState({
            hover: false
        });
        console.log('leave');
    },
    render: function() {
        var inner = normal;
        if(this.state.hover) {
            inner = hover;
        }

        return (
            <div style={outer}>
                <div style={inner}
                    onMouseEnter={this.onMouseEnterHandler}
                    onMouseLeave={this.onMouseLeaveHandler} >
                    {this.props.children}
                </div>
            </div>
        );
    }
});

var outer = {
    height: '120px',
    width: '200px',
    margin: '100px',
    backgroundColor: 'green',
    cursor: 'pointer',
    position: 'relative'
}

var normal = {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: 'red',
    opacity: 0
}

var hover = {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: 'red',
    opacity: 1
}

React.render(
    <Hover></Hover>,         
    document.getElementById('container')
)

1
제안 해 주셔서 감사합니다. 나는 지금 그것을 질문으로 다시 썼다.
HelpMeStackOverflowMyOnlyHope

문제가 무엇인지 아직 명확하지 않으므로 문제를 강조하는 코드 예제 (이상적으로는 jsFiddle 또는 이와 동등한 것)를 추가하십시오. "이벤트가 등록되었습니다"란 무슨 뜻입니까?
WiredPrairie

@HelpMeStackOverflowMyOnlyHope 대답을 선택하고 싶습니까? stackoverflow.com/a/35619979/1579789 감사합니다!
Elon Zito

답변:


92

이것들 중 하나를 시도해 보셨습니까?

onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp

SyntheticEvent

또한 다음을 언급합니다.

React는 여러 브라우저에서 일관된 속성을 갖도록 이벤트를 정규화합니다.

아래 이벤트 핸들러는 버블 링 단계의 이벤트에 의해 트리거됩니다. 캡처 단계에 대한 이벤트 핸들러를 등록하려면 이벤트 이름에 Capture를 추가하십시오. 예를 들어 onClick을 사용하는 대신 onClickCapture를 사용하여 캡처 단계에서 클릭 이벤트를 처리합니다.


4
문서에서 onMouseEnter 및 onMouseLeave에 대해 언급합니다.The onMouseEnter and onMouseLeave events propagate from the element being left to the one being entered instead of ordinary bubbling and do not have a capture phase.
P Fuster

39

이전 답변은 매우 혼란 스럽습니다. 이 문제를 해결하기 위해 반응 상태 나 특별한 외부 라이브러리가 필요하지 않습니다. 순수한 CSS / SS로 달성 할 수 있습니다.

스타일 :

.hover {
  position: relative;

  &:hover &__no-hover {
    opacity: 0;
  }

  &:hover &__hover {
    opacity: 1;
  }

  &__hover {
    position: absolute;
    top: 0;
    opacity: 0;
  }

  &__no-hover {
    opacity: 1;
  }
}

반응 컴포넌트

간단한 Hover순수 렌더링 기능 :

const Hover = ({ onHover, children }) => (
    <div className="hover">
        <div className="hover__no-hover">{children}</div>
        <div className="hover__hover">{onHover}</div>
    </div>
)

용법

그런 다음 다음과 같이 사용하십시오.

    <Hover onHover={<div> Show this on hover </div>}>
        <div> Show on no hover </div>
    </Hover>

1
:이 답변을 원하는 수 stackoverflow.com/a/50342093/101290
보 스미스

2
이 질문에 대한 최고의 답변입니다.
도구

20

당신이 사용할 수있는 onMouseOver={this.onToggleOpen}onMouseOut={this.onToggleOpen}이상 뮤즈와 구성 요소에 출력하기


저에게 완벽하게 작동했습니다. 감사합니다. 그러나 예를 들어 "onMauseOverFirstTime"이 존재하는 것과 같은 다른 기능에 어떻게 액세스 할 수 있습니까? 그 정보는 어디서 얻었습니까?
SmoggeR_js

1
@MtgKhaJeskai reactjs.org/docs/events.html onMouseOverFirstTime과 같은 sth를 원한다면 직접 생성해야합니다. 예를 들어, 상태의 'firstMouseOver'가 true 일 때만 함수를 실행하고 다음과 같은 경우 false로 설정합니다. 함수가 한 번 호출되었습니다.
cubefox

내가 설립했습니다! 대단히 감사합니다! : D
SmoggeR_js

아니요, "onMauseOverFirstTime"함수가 없습니다. "onMouseover와"@MtgKhaJeskai에 사실을 및 확인 ": {거짓 isFirstTime을} 상태"그러나 당신은 당신의 상태에 이것을 추가,이 작업을 수행하는 플래그를 사용할 수 있습니다
Behnam Eskandari

12

onMouseEnter / onMouseLeave 또는 onMouseDown / onMouseUp 버그를 보여주는 작은 데모를 제작할 수 있다면, ReactJS의 이슈 페이지 또는 메일 링리스트에 게시하여 질문을 제기하고 개발자가 그것에 대해 말하는 것을 듣는 것이 좋습니다.

귀하의 사용 사례에서 CSS : hover 및 : active 상태가 귀하의 목적에 충분하다는 것을 암시하는 것 같으므로 사용하는 것이 좋습니다. CSS는 브라우저에서 직접 구현되기 때문에 Javascript보다 훨씬 빠르고 안정적입니다.

그러나 : hover 및 : active 상태는 인라인 스타일에서 지정할 수 없습니다. 할 수있는 일은 요소에 ID 또는 클래스 이름을 할당하고 스타일 시트에 스타일을 작성하는 것입니다 (애플리케이션에서 다소 일정한 경우) 또는 동적으로 생성 된 <style>태그에 스타일을 작성하는 것입니다.

후자 기술의 예는 다음과 같습니다. https://jsfiddle.net/ors1vos9/


@clusterBuddy 코드가 정확하고 항상 잘 작동했기 때문에 JsFiddle 또는 라이브러리의 버그라고 생각합니다.
Tobia

10

참고 : 이 답변은 질문 asker가 JavaScript를 사용하여 CSS 스타일을 적용하려는이 질문의 이전 버전에 대한 것입니다. CSS로 간단히 수행 할 수 있습니다.

단순한 css솔루션입니다.

기본 스타일을 적용 할 때 CSS는 JS 솔루션보다 99 % 더 간단하고 성능이 뛰어납니다. (더 현대적인 CSS-in-JS 솔루션 (예 : React Components 등)이 더 유지 관리 가능하지만)

이 코드 스 니펫을 실행하여 실제로 확인하세요.

.hover-button .hover-button--on,
.hover-button:hover .hover-button--off {
  display: none;
}

.hover-button:hover .hover-button--on {
  display: inline;
}
<button class='hover-button'>
  <span class='hover-button--off'>Default</span>
  <span class='hover-button--on'>Hover!</span>
</button>


11
이것은 질문에 대한 답이 아닙니다.
tsujin

@tsujin-위의 참고 사항을 참조하십시오.
Beau Smith

more performant that JS solutions 99% of the time사실이 아니다. 이 신화를 폭로하는 기사를 읽으십시오. 출처가 있습니까?
Claudiu Creanga 2019 년

@ClaudiuCreanga-이 신화를 폭로하는 기사를 링크하십시오.
Beau Smith

1
@ClaudiuCreanga-당신이 반대하는 문장을 더 간결하게 설명했습니다.
Beau Smith

9

비활성화 된 버튼에서 onMouseLeave 이벤트를 수신 할 때 이와 동일한 문제가 발생했습니다. 비활성화 된 버튼을 감싸는 요소에서 기본 mouseleave 이벤트를 수신하여이 문제를 해결했습니다.

componentDidMount() {
    this.watchForNativeMouseLeave();
},
componentDidUpdate() {
    this.watchForNativeMouseLeave();
},
// onMouseLeave doesn't work well on disabled elements
// https://github.com/facebook/react/issues/4251
watchForNativeMouseLeave() {
    this.refs.hoverElement.addEventListener('mouseleave', () => {
        if (this.props.disabled) {
            this.handleMouseOut();
        }
    });
},
render() {
    return (
        <span ref='hoverElement'
            onMouseEnter={this.handleMouseEnter}
            onMouseLeave={this.handleMouseLeave}
        >
            <button disabled={this.props.disabled}>Submit</button>
        </span>
    );
}

여기 바이올린입니다 https://jsfiddle.net/qfLzkz5x/8/


이 접근하지 않습니다 작업, 신뢰할 수있는 방법이 없기 때문에 onMouseLeave- 이벤트를
dreampulse

바이올린을 확인 했습니까? 마우스를 내릴 때 이벤트가 두 번 던진다는 점을 제외하고는 잘 작동하는 것 같습니다.
Cory Danielson

자주 작동하지만 항상 그런 것은 아닙니다! 이 설명을 참조하십시오 : stackoverflow.com/questions/7448468/...이
dreampulse

5

라는 패키지는 styled-components이 문제를 우아한 방식으로 해결할 수 있습니다 .

참고

  1. Glen Maddern-스타일이 지정된 구성 요소로 React 앱 스타일 지정

const styled = styled.default
const Square = styled.div`
  height: 120px;
  width: 200px;
  margin: 100px;
  background-color: green;
  cursor: pointer;
  position: relative;
  &:hover {
    background-color: red;
  };
`
class Application extends React.Component {
  render() {
    return (
      <Square>
      </Square>
    )
  }
}

/*
 * Render the above component into the div#app
 */
ReactDOM.render(<Application />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>
<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>
<div id='app'></div>


2

인라인 스타일링만으로는 불가능합니다. JavaScript에서 CSS 기능을 다시 구현하는 것을 권장하지 마십시오. 우리는 이미이 사용 사례를 위해 매우 강력하고 믿을 수 없을 정도로 빠른 언어 인 CSS를 가지고 있습니다. 그래서 그것을 사용하십시오! 만든 스타일 그것은 도움이됩니다.

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;

1

라듐 사용 !

다음은 해당 웹 사이트의 예입니다.

var Radium = require('radium');
var React = require('react');
var color = require('color');

@Radium
class Button extends React.Component {
  static propTypes = {
    kind: React.PropTypes.oneOf(['primary', 'warning']).isRequired
  };

  render() {
    // Radium extends the style attribute to accept an array. It will merge
    // the styles in order. We use this feature here to apply the primary
    // or warning styles depending on the value of the `kind` prop. Since its
    // all just JavaScript, you can use whatever logic you want to decide which
    // styles are applied (props, state, context, etc).
    return (
      <button
        style={[
          styles.base,
          styles[this.props.kind]
        ]}>
        {this.props.children}
      </button>
    );
  }
}

// You can create your style objects dynamically or share them for
// every instance of the component.
var styles = {
  base: {
    color: '#fff',

    // Adding interactive state couldn't be easier! Add a special key to your
    // style object (:hover, :focus, :active, or @media) with the additional rules.
    ':hover': {
      background: color('#0074d9').lighten(0.2).hexString()
    }
  },

  primary: {
    background: '#0074D9'
  },

  warning: {
    background: '#FF4136'
  }
};


3
사용자가 요청한 요소 위에 커서가있을 때 코드를 안정적으로 실행하는 방법이 아니라 인라인 스타일을 사용하여 hover CSS 효과를 적용하는 방법을 보여줍니다.
Gunchars

내 대답이 왜 받아 들여지지 않았는지 모르겠습니다.
fkilaiwi

2
@Gunchars " 인라인 스타일링을 할 때 ReactJS에서 호버 이벤트 또는 활성 이벤트를 어떻게 얻을 수 있습니까? ". OP의 질문의 첫 문장. 그가 요청한 것과 거의 동일합니다.
trixn

1

onMouseOver 및 onMouseOut을 사용합니다. React의 원인

onMouseEnter 및 onMouseLeave 이벤트는 일반 버블 링 대신 남아있는 요소에서 입력중인 요소로 전파되며 캡처 단계가 없습니다.

여기 마우스 이벤트 에 대한 React 문서 에 있습니다.


0

onMouseEnter가 호출되었을 때 비슷한 문제가 있었지만 때때로 해당 onMouseLeave 이벤트가 발생하지 않았습니다. 여기에 잘 작동하는 해결 방법이 있습니다 (부분적으로 jQuery에 의존).

var Hover = React.createClass({
    getInitialState: function() {
        return {
            hover: false
        };
    },
    onMouseEnterHandler: function(e) {
        this.setState({
            hover: true
        });
        console.log('enter');

        $(e.currentTarget).one("mouseleave", function (e) {
            this.onMouseLeaveHandler();
        }.bind(this));

    },
    onMouseLeaveHandler: function() {
        this.setState({
            hover: false
        });
        console.log('leave');
    },
    render: function() {
        var inner = normal;
        if(this.state.hover) {
            inner = hover;
        }

        return (
            <div style={outer}>
                <div style={inner}
                    onMouseEnter={this.onMouseEnterHandler} >
                    {this.props.children}
                </div>
            </div>
        );
    }
});

jsfiddle 참조 : http://jsfiddle.net/qtbr5cg6/1/


왜 그런 일이 일어 났습니까? (제 경우) : $('#item').animate({ scrollTop: 0 })항목을 클릭 할 때 jQuery 스크롤 애니메이션 (를 통해 )을 실행하고 있습니다. 따라서 커서는 "자연스럽게"항목을 떠나지 않지만 JavaScript 기반 애니메이션 동안 ...이 경우 onMouseLeave가 React (React 15.3.0, Chrome 51, Desktop)에 의해 제대로 실행되지 않았습니다.


0

이 질문을 한 지 오래되었지만 onMouseLeave ()와 일치하지 않는 동일한 문제가 발생했습니다. 내가 한 일은 드롭 목록에 onMouseOut ()을 사용하고 전체 메뉴에 대해 마우스를 떠날 때입니다. 신뢰할 수 있고 테스트 할 때마다 작동합니다. 여기 문서에서 이벤트를 보았습니다 : https://facebook.github.io/react/docs/events.html#mouse-events 여기에 https://www.w3schools.com/bootstrap/bootstrap_dropdowns.asp 를 사용한 예가 있습니다. :

handleHoverOff(event){
  //do what ever, for example I use it to collapse the dropdown
  let collapsing = true;
  this.setState({dropDownCollapsed : collapsing });
}

render{
  return(
    <div class="dropdown" onMouseLeave={this.handleHoverOff.bind(this)}>
      <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
      <span class="caret"></span></button>
      <ul class="dropdown-menu" onMouseOut={this.handleHoverOff.bind(this)}>
        <li><a href="#">bla bla 1</a></li>
        <li><a href="#">bla bla 2</a></li>
        <li><a href="#">bla bla 3</a></li>
      </ul>
    </div>
  )
}

0

개인적 으로 React에서 인라인 스타일로 Style It 을 사용 하거나 CSS 또는 SASS 에서 개별적으로 스타일을 유지합니다. 파일 합니다.

그러나 인라인으로 작업하는 데 정말로 관심이 있다면 라이브러리를 살펴보십시오. 아래 사용법 중 일부를 공유합니다.

구성 요소에서 :

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

class Intro extends React.Component {
  render() {
    return (
      <Style>
        {`
          .intro {
            font-size: 40px;
          }
        `}

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

export default Intro;

출력 :

    <p class="intro _scoped-1">
      <style type="text/css">
        ._scoped-1.intro {
          font-size: 40px;
        }
      </style>

      CSS-in-JS made simple -- just Style It.
    </p>


또한 다음과 같이 CSS에서 마우스 오버와 함께 JavaScript 변수를 사용할 수 있습니다.

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

class Intro extends React.Component {
  render() {
    const fontSize = 13;

    return Style.it(`
      .intro {
        font-size: ${ fontSize }px;  // ES2015 & ES6 Template Literal string interpolation
      }
      .package {
        color: blue;
      }
      .package:hover {
        color: aqua;
      }
    `,
      <p className="intro">CSS-in-JS made simple -- just Style It.</p>
    );
  }
}

export default Intro;

결과는 다음과 같습니다.

<p class="intro _scoped-1">
  <style type="text/css">
    ._scoped-1.intro {
      font-size: 13px;
    }
    ._scoped-1 .package {
      color: blue;
    }
    ._scoped-1 .package:hover {
      color: aqua;
    }
  </style>

  CSS-in-JS made simple -- just Style It.
</p>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.