Reputation: 25
I tried many different syntaxes, but I couldn't make this work. I'm trying to access a wrapped component's div element inside HOC so that I could use it to init my google map instance, which requires a HTML node as a first parameter. I'm not using class components. As I understand I need to create ref in child component and forwardRef in HOC. But I also tried doing it the opposite way but no luck. My current code looks like this:
const withMap = (OriginalComponent) => {
const NewComponent = (props) => {
scriptLoader("https://maps.googleapis.com/maps/api/js?key=?&libraries=geometry&")
.then((res) => {
console.log(res)
const map = new window.google.maps.Map(forwardedRef.current, {
center: {lat: parseFloat(54.9065), lng: parseFloat(25.3189)},
zoom: 6
})
})
.catch((err) => {
console.log(err);
})
return <OriginalComponent name="hello" />
}
//return NewComponent;
return React.forwardRef((props, ref) => {
return <NewComponent {...props} forwardedRef={ref} />;
});
}
Wrapped component:
const Map = (props) => {
const mapRef = useRef();
const { name } = props;
useEffect(() => {
console.log(mapRef)
})
return (
<div>
<div className="map" style={mapStyles} name={name} ref={mapRef} ></div>
</div>
);
}
const mapStyles = {
height: 100 + "vh"
}
export default withMap(Map);
Upvotes: 0
Views: 515
Reputation: 876
Okay, I figured this out. The problem was that I was receiving refs in my HOC, whereas I should have done that in my wrapped component instead. React.forwardRef
is a little bit misleading name I would say.
Since in HOC NewComponent
basically refers to any component that we wrap it with HOC, we can create a reference using useRef
hook in this HOC new returned component and reference our OriginalComponent. Now if we don't forward the ref, it will just reference the component itself and not a div inside the component. So inside the wrapped component Map.js
we need to catch this ref using React.forwardRef(props, ref)
and finally set the ref to a div element inside the return statement <div className="map" style={mapStyles} name={name} ref={ref} ></div>
.
Full example:
const withMap = (OriginalComponent) => {
const NewComponent = (props) => {
const mapRef = useRef();
scriptLoader("https://maps.googleapis.com/maps/api/js?key=?&libraries=geometry&")
.then((res) => {
console.log(res)
const map = new window.google.maps.Map(mapRef.current, {
center: {lat: parseFloat(54.9065), lng: parseFloat(25.3189)},
zoom: 6
})
})
.catch((err) => {
console.log(err);
})
return <OriginalComponent name="hello" ref={mapRef} />
}
return NewComponent;
}
Original wrapped component:
const Map = React.forwardRef((props, ref) => {
const { name } = props;
useEffect(() => {
})
return (
<div>
<div className="map" style={mapStyles} name={name} ref={ref} ></div>
</div>
);
});
Upvotes: 3