I am learning react and I have some code which waits for a hover over a button and then applies an opaque white overlay over the image over which you hover (and this works):
class Product extends Component {
constructor(props) {
super(props);
// 1. bind your functions in the constructor.
this.mouseOver = this.mouseOver.bind(this);
this.mouseOut = this.mouseOut.bind(this);
this.state = {
hover: false
};
}
// 2. bind it with fat arrows.
mouseOver = () => {
this.setState({hover: true});
}
mouseOut() {
this.setState({hover: false});
}
render() {
return (
<Link to={"/products/"+this.props.value.uid}>
<button className="Product" onMouseEnter={this.mouseOver.bind(this)} onMouseLeave={this.mouseOut.bind(this)}>
<img className="ImageGrid" src={this.props.value.media}/>
{this.state.hover ? (
<div className="ImageOverlay">
<div className="TextOverlay">
<p><b>{this.props.value.name}</b></p>
<p>${this.props.value.price}</p>
</div>
</div>) : null}
</button>
</Link>
);
}
}
My question is... let's say that instead of adding an overlay over the image rendered by this ponent, I wanted to change an image rendered by another ponent and not by applying an overlay div, but by changing some CSS setting of said image, like applying a filter: filter: grayscale(100%). So there is this image:
<img className="PicBox" src={this.state.img[sid-1]} />
Rendered by another ponent.
Here is what I am thinking the strategy might be:
Have my original ponent (the one over which I hover), have a prop "state" which keeps track on whether or not i hover over it, like I did above.
In the other ponent which renders ImageX, I need to somehow access the prop of the Hover ponent, and check its state, to decide how to render the image (with grayscale or not).
How do I access state of the hover ponent within another ponent?
(Or if my strategy is off, a hint would be appreciated)
I am learning react and I have some code which waits for a hover over a button and then applies an opaque white overlay over the image over which you hover (and this works):
class Product extends Component {
constructor(props) {
super(props);
// 1. bind your functions in the constructor.
this.mouseOver = this.mouseOver.bind(this);
this.mouseOut = this.mouseOut.bind(this);
this.state = {
hover: false
};
}
// 2. bind it with fat arrows.
mouseOver = () => {
this.setState({hover: true});
}
mouseOut() {
this.setState({hover: false});
}
render() {
return (
<Link to={"/products/"+this.props.value.uid}>
<button className="Product" onMouseEnter={this.mouseOver.bind(this)} onMouseLeave={this.mouseOut.bind(this)}>
<img className="ImageGrid" src={this.props.value.media}/>
{this.state.hover ? (
<div className="ImageOverlay">
<div className="TextOverlay">
<p><b>{this.props.value.name}</b></p>
<p>${this.props.value.price}</p>
</div>
</div>) : null}
</button>
</Link>
);
}
}
My question is... let's say that instead of adding an overlay over the image rendered by this ponent, I wanted to change an image rendered by another ponent and not by applying an overlay div, but by changing some CSS setting of said image, like applying a filter: filter: grayscale(100%). So there is this image:
<img className="PicBox" src={this.state.img[sid-1]} />
Rendered by another ponent.
Here is what I am thinking the strategy might be:
Have my original ponent (the one over which I hover), have a prop "state" which keeps track on whether or not i hover over it, like I did above.
In the other ponent which renders ImageX, I need to somehow access the prop of the Hover ponent, and check its state, to decide how to render the image (with grayscale or not).
How do I access state of the hover ponent within another ponent?
(Or if my strategy is off, a hint would be appreciated)
Share Improve this question asked Apr 19, 2017 at 21:01 RebeccaK375RebeccaK375 9013 gold badges18 silver badges30 bronze badges 6- are you using something like redux? – xDreamCoding Commented Apr 19, 2017 at 21:11
- What is the relationship between two ponents? Parent-child, sibling, etc? – dfsq Commented Apr 19, 2017 at 21:12
- @dfsq - Right now, these are just two ponents side by side (sibling), rendered by mon parents. – RebeccaK375 Commented Apr 19, 2017 at 21:13
- 2 @RebeccaK375 you could handle the state in the parent and pass a callback as a prop which gets called when there is a hover. In this callback you can now change some variables in the parent and render your image overlay accordingly. – xDreamCoding Commented Apr 19, 2017 at 21:14
- 1 Ahh, so let me just repeat it to check if I got it. Let's say I have some ponent which renders both: HoverComponent and ImageComponent. I can have the parent have a prop, along with its own hover state. I can bind this hover to the div containin Hover Component and then render Image depending on whether hover is true. I see! If you post this, I will accept as an answer. Thank you. – RebeccaK375 Commented Apr 19, 2017 at 21:18
4 Answers
Reset to default 4As long as you don't use some state managing library such as redux or flux and you want to access state between ponents, you need a mon parent between those. In the end you have something like this (pseudocode):
ParentComponent {
hoverHandler(isHover) {
this.childIsHover = isHover;
}
render() {
<hoverComponent onHover={this.hoverHandler} />
<imageComponent overlay={this.childIsHover} />
}
}
When working with React, you've got to think about who should have the responsibility of maintaining state. So in this case, the state should not be stored in the button ponent, because it needs to be accessed by another ponent which is not one of its children.
Instead, you should create a parent ponent that is responsible for storing the hover state, and also renders both the button and image ponents. You can bind functions to the parent, so that when they are passed as props to other children, they can still update the state of the parent.
So for example, your parent ponent might look like this:
class Parent extends Component {
constructor () {
super()
this.state = {
hover: false
}
this.updateHoverState = this.updateHoverState.bind(this)
}
updateHoverState (hover) {
this.setState({ hover: hover })
}
render () {
<div>
<ButtonComponent updateHoverState={this.updateHoverState} />
<ImageComponent hover={this.state.hover} />
</div>
}
}
Now, your button ponent can just be a function, and does not need to maintain
any state of its own. You can update the parent state by calling
this.props.updateHoverState
:
function ButtonComponent (props) {
return (
<button
onMouseEnter={() => this.props.updateHoverState(true)}
onMouseLeave={() => this.props.updateHoverState(false)}
/>
)
}
In React, you generally pass properties down to children ponents. So rather than trying to "reach up and over" into an unrelated ponent to access it's state, you should be accessing a state that's been passed down to your from a shared parent ponent.
So if the ImageX ponent is a child of Product, you can pass the state directly into it <ImageX hover={this.state.hover} />
. You can then access hover
in the ImageX props.
If it's not a child of Product, you'll want to pass down the state from a shared parent and access it from both ponents.
You can use Context and make a theme-like color set for your ponents. Read about the context in the docs and codeburst.