Reputation: 221
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);
Upvotes: 22
Views: 76323
Reputation: 553
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.
Upvotes: 1
Reputation: 323
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.
Upvotes: 4
Reputation: 1485
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>
Upvotes: 1
Reputation: 1694
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.
Upvotes: 0
Reputation: 40927
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/
Upvotes: 47
Reputation: 86230
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.
Upvotes: 12