Skip to content

Commit

Permalink
22. withHover
Browse files Browse the repository at this point in the history
  • Loading branch information
tylermcginnis committed Mar 15, 2019
1 parent ce50e03 commit 64355d5
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 37 deletions.
50 changes: 13 additions & 37 deletions app/components/Tooltip.js
@@ -1,5 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
import withHover from './withHover'

const styles = {
container: {
Expand All @@ -23,43 +24,18 @@ const styles = {
}
}

export default class Tooltip extends React.Component {
constructor(props) {
super(props)

this.state = {
hovering: false,
}

this.mouseOver = this.mouseOver.bind(this)
this.mouseOut = this.mouseOut.bind(this)
}
mouseOver() {
this.setState({
hovering: true
})
}
mouseOut() {
this.setState({
hovering: false
})
}
render() {
const { text, children } = this.props
const { hovering } = this.state

return (
<div
onMouseOver={this.mouseOver}
onMouseOut={this.mouseOut}
style={styles.container}>
{hovering === true && <div style={styles.tooltip}>{text}</div>}
{children}
</div>
)
}
function Tooltip ({ text, children, hovering }) {
return (
<div style={styles.container}>
{hovering === true && <div style={styles.tooltip}>{text}</div>}
{children}
</div>
)
}

Tooltip.propTypes = {
text: PropTypes.string.isRequired
}
text: PropTypes.string.isRequired,
hovering: PropTypes.bool.isRequired,
}

export default withHover(Tooltip)
38 changes: 38 additions & 0 deletions app/components/withHover.js
@@ -0,0 +1,38 @@
import React from 'react'

export default function withHover (Component, propName = 'hovering') {
return class WithHover extends React.Component {
constructor(props) {
super(props)

this.state = {
hovering: false,
}

this.mouseOver = this.mouseOver.bind(this)
this.mouseOut = this.mouseOut.bind(this)
}
mouseOver() {
this.setState({
hovering: true
})
}
mouseOut() {
this.setState({
hovering: false
})
}
render () {
const props = {
[propName]: this.state.hovering,
...this.props
}

return (
<div onMouseOver={this.mouseOver} onMouseOut={this.mouseOut}>
<Component {...props} />
</div>
)
}
}
}

4 comments on commit 64355d5

@akkdio
Copy link

@akkdio akkdio commented on 64355d5 Jun 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be obvious to some but I found I could not change the name of hovering in ToolTip, for example to "hover" in lines 27 and 30 above without also changing the propName in line 3 of withHover to "hover". Leaving line 3's propName to "hovering" resulted in an error undefined. Warning: Failed prop type: The prop hoveringis marked as required inToolTip, but its value is undefined.

@arpan-banerjee7
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understood how Higher order functions work, Here it is passed a function like this which is later rendered -->
export default withHover(Tooltip)
My question is can we do something so that we can render like this by exporting it.

@arpan-banerjee7
Copy link

@arpan-banerjee7 arpan-banerjee7 commented on 64355d5 Aug 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I achieved it by doing this inside the Popular component-->and i exported the Tootltip function as well.

import Tooltip from "./Tooltip";
import WithHover from "./withHover";
...
function ReposGrid({ repos }) {
const ToolTipWithHover = WithHover(Tooltip);
....
<ToolTipWithHover text="Github username">
       <FaUser color="rgb(255, 191, 116)" size={22} />
       <a href={`https://github.com/${login}`}>{login}</a>
</ToolTipWithHover>

@yjeong19
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be obvious to some but I found I could not change the name of hovering in ToolTip, for example to "hover" in lines 27 and 30 above without also changing the propName in line 3 of withHover to "hover". Leaving line 3's propName to "hovering" resulted in an error undefined. Warning: Failed prop type: The prop hoveringis marked as required inToolTip, but its value is undefined.

I think propName='hover' is a default parameter and shoudn't need to be changed. If you pass in 'hover' as a parameter to withHover(Tooltip, 'hover'), you wont get that error message.

Please sign in to comment.