23

i would like to ask how to make a button but when the mouse is on the button (hover),the new button is displayed above the previous button... and it's in react.js.. thx

this is the way of my code..

var Category = React.createClass({displayName: 'Category',
  render: function () {
      return (
        React.createElement("div", {className: "row"}, 
        React.createElement("button", null, "Search",   {OnMouseEnter://I have no idea until here})
      )
    );
  }
});

React.render(React.createElement(Category), contain);
4
  • It really seems to me that you don't want to create another button.. you probably just want to change the style/behavior of the current button Commented Jan 21, 2015 at 16:36
  • sorry here is my current code: Commented Jan 21, 2015 at 17:30
  • 1
    i need to know to how to use onMouseEnter function Commented Jan 21, 2015 at 17:31
  • @Randy Morris has the correct answer, but why not use JSX (the html-like) syntax for your div and button? Commented Oct 28, 2016 at 22:00

6 Answers 6

47

If I understand correctly you're trying to create a whole new button. Why not just change the label/style of the button as @André Pena suggests?

Here is an example:

var HoverButton = React.createClass({
    getInitialState: function () {
        return {hover: false};
    },

    mouseOver: function () {
        this.setState({hover: true});
    },

    mouseOut: function () {
        this.setState({hover: false});
    },

    render: function() {
        var label = "foo";
        if (this.state.hover) {
            label = "bar";
        }
        return React.createElement(
            "button",
            {onMouseOver: this.mouseOver, onMouseOut: this.mouseOut},
            label
        );
    }
});

React.render(React.createElement(HoverButton, null), document.body);

Live demo: http://jsfiddle.net/rz2t224t/2/

Sign up to request clarification or add additional context in comments.

6 Comments

thanks @Randy Morris, but what I need to do is to create a new button above the previous button when it's hover.. not to change the label..
@WidyGui Can you explain why?
I've updated the example from Randy: jsfiddle.net/pqr/rz2t224t/3 - now it shows additional button above.
@Petr ahh, I maybe mistook "above" to mean "on top of". Given OPs comments this is probably what he's looking for, you should post it as its own answer.
@RandyMorris I need to implement this in functional React component. Could you let know how can it be achieved
|
12

You should probably just use CSS for this, but if you insist on doing it in JS you simply set flag in state to true in your onMouseEnter, and set the same flag to false in onMouseLeave. In render you render the other button if the flag is true.

Nothing fancy or complicated involved.

1 Comment

I ran into an issue using this. I had a menu over the top of the div where I was tracking hover state. After selecting an entry from the menu, the popover would disappear, but since I didn't move the mouse, the onMouseLeave event wouldn't fire. Using onMouseOver and onMouseOut seems to have fixed that.
4

Here is my Solution for the Functional Based Components. I'm assuming that you're looking to change the colour of the button on the "mouse hover" event. You can use anything by following my code though.

Please import useState and useEffect hook as

import React, { useState, useEffect } from 'react';

Now, Make the state as:-

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

Define the colour that you want to render on Mouse Hover, I'm defining primary colour and mouseOverColor here.

let primaryColor:red
let mouseOverColor:blue

Now in JSX of Reactjs.

return (<div>

<Button
      
      style={backGroundColor: hover === true ? mouseOverColor : primaryColor}
      onMouseOver={(e) => {
        e.preventDefault();
        setHover(true);
      }}
      onMouseLeave={(e) => {
        e.preventDefault();
        setHover(false);
      }}
    >
      Say hi
    </Button>

</div>)

Please make sure to use useEffect dependency with the "hover" property so it should refresh background colour whenever the component gets mouseover effect as:-

  useEffect(() => {}, [hover]);

Note:- I use button of Material UI, you can use plain HTML button too.

import { Button } from '@material-ui/core';

RESULT:- Norammly button would be Red and on Mouse Hover, it should be red and vice versa. That's pretty much it.

Comments

1

I'm not sure when you would like to show a first button (above) only when the second button is hovered. If the mouse hover is removed from the second button the first button would be disappear again. But I guess the question was to show it and also make it interactable.

In React you would use the state for that. In a functional React component the useState hook is the best option. The onMouseOver event on the button changes the state variable on hover by calling the setShowButtons function. I usually toggle CSS classes based on the variable (showButtons in this example) but one could also use conditional render as button #3 in the this example.

Showing button #1 above when button #2 is hovered is also possible with only CSS. In this example with flex-box (reversing the order of the two buttons) and the sibling selector (~).

const App = () => {
  const [showButtons, setShowButtons] = React.useState(false);
  return (
    <main className="main-container">
      <h4>Show buttons with React state</h4>
      <button className={showButtons ? "button" : "button _hide"}>
        #1. I'm shown with a CSS transition when #2 is hovered
      </button>
      <button
        className="button"
        onMouseOver={() => setShowButtons(true)}
        onFocus={() => setShowButtons(true)}
        onMouseOut={() => setShowButtons(false)}
        onBlur={() => setShowButtons(true)}
      >
        #2. Hover me to show #1 and #3 button
      </button>
      {showButtons && (
        <button className="button">
           #3. I'm rendered when #2 is on hovered
        </button>
      )}
      <hr />
      <h4>Show button with CSS only</h4>
      <div className="reversed-container">
        <button className="button-2">#2. Hover me to show button #1</button>
        <button className="button-2 _hide">
          #1. I'm shown with a CSS transition when #2 is hovered
        </button>
      </div>
    </main>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
.main-container {
  display: flex;
  flex-direction: column;
}

.reversed-container {
  display: flex;
  flex-direction: column-reverse;
}

hr {
  width: 100%;
  margin-top: 1rem;
}

.button,
.button-2 {
  padding: 1rem;
  transition: opacity 1s;
}

.button._hide,
.button-2._hide {
  opacity: 0;
  pointer-events: none;
}


.button:hover,
.button-2:hover {
  opacity: 1;
  pointer-events: initial;
  background-color: lightyellow;
}

.button-2:hover ~ .button-2._hide {
  opacity: 1;
  pointer-events: initial;
  background-color: lightyellow;
}
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>

<div id="root"></div>

Comments

1

easy & simple way to do this with hooks:

import React, { useState } from "react";

export default function App() {
  const [hover, setHover] = useState(false);

  const handleMouseIn = () => {
    setHover(true);
  };

  const handleMouseOut = () => {
    setHover(false);
  };

  return (
    <div>
      <button onMouseOver={handleMouseIn} onMouseOut={handleMouseOut}>
        {hover ? "foo" : "bar"}
      </button>
    </div>
  );
}

we have the hover state to track whether we hovered over the button or not. we set it to true in handleMouseIn and false in handleMouseOut. we set onMouseOver to handleMouseIn and onMouseOut to handleMouseOut.

This way, hover is true when we hovered over the button and false otherwise.

Comments

0

I just read some tutorials about react.js, and I found this solution.

For the sake of reusability, and to separate out the "hover" logic, you can create a component to replace your normal tag.

Something like this:

var React = require('react');
var classNames = require('classnames');
var HoverHandlers = require('./HoverHandlers.jsx');

var ElementHover = React.createClass({
  mixins: [HoverHandlers],

  getInitialState: function () {
    return { hover: false };
  },

  render: function () {
    var hoverClass = this.state.hover ? this.props.hoverClass : '';
    var allClass = classNames(this.props.initialClasses, hoverClass);

    return (
      <this.props.tagName 
                          className={allClass} 
                          onMouseOver={this.mouseOver} 
                          onMouseOut={this.mouseOut}>
        {this.props.children}
      </this.props.tagName>
    );
  }

});

module.exports = ElementHover;

The HoverHandlers mixin is like (you can also add handlers for :active :focus, etc...):

var React = require('react');

var HoverHandlers = {
  mouseOver: function (e) {
    this.setState({ hover: true });
  },
  mouseOut: function (e) {
    this.setState({ hover: false });
  },
};  
module.exports = HoverHandlers;

You then can use the component like this:

<ElementHover tagName="button" hoverClass="hover" initialClasses="btn btn-default" >
          Label or content of the button
</ElementHover>

The code might need to be optimized. So, many thanks to anyone can help me about that.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.