Reputation: 536
I'm creating a custom mouse cursor per component (e.g. a custom mouse cursor on a figure element). I'm writing a custom hook for this. This is the hook so far:
const useMouseCoords = () => {
let [coords, setCoords] = useState({ x: 0, y: 0 })
// I need to calculate the coordinates from the parents offset. Here is where I'm stuck.
let offsetParent = parentRef.current.getBoundingClientRect()
function handleCoords(e) {
setCoords({
x: e.clientX - offsetParent.x,
y: e.clientY - offsetParent.y,
})
}
useEffect(() => {
if (typeof window === `undefined`) return // escape gatsby build process
window.addEventListener('mousemove', handleCoords)
return () => {
window.removeEventListener('mousemove', handleCoords)
}
}, [])
return coords
}
The mousecursor component is quite simple:
const MouseCursor = (props) => {
let { x, y } = useMouseCoords()
return (
<div
className="mouse-cursor-button"
style={{
transform: `translate(${x}px, ${y}px)`,
}}
>
<div className="mouse-cursor-button__text">Click to play</div>
</div>
)
}
Code of course doesn't work but is rather to illustrate what I'm trying to achieve.
So I need the parent of the MouseCursor component to calculate the offset. I'm stuck at the part where I want to reference the parent component. I was hoping I could pass it as an argument to the hook.
So the question is how can I access the parent component in the hook?
Upvotes: 1
Views: 3060
Reputation: 2928
Can you not just pass the ref down like:
function Parent() {
const ref = useRef()
return <div ref={ref}><MouseCursor parentRef={ref} /></div>
}
const MouseCursor = (props) => {
let { x, y } = useMouseCoords(props.parentRef)
return (
<div
className="mouse-cursor-button"
style={{
transform: `translate(${x}px, ${y}px)`,
}}
>
<div className="mouse-cursor-button__text">Click to play</div>
</div>
)
}
See https://codesandbox.io/s/0y46034oyl?fontsize=14 for example
Upvotes: 3
Reputation: 782
You can have a function in the parent component that interacts with it's state and then the uses its state in the props of the children.
class Parent extends Component{
constructor(props){
super(props);
this.state = {
x: 0,
y:0
};
}
//...
function setCoords(x, y){
this.setState({
x: x,
y: y
})
}
//...
render(){
return(
<Child
actions={ {setParentCoords: this.setCoords.bind(this)} }
x={ this.state.x }
y={ this.state.y }
)
}
Now in your child you have access to props.actions.setParentCoords()
Upvotes: 0