简体   繁体   中英

How to access a div element of a wrapped component in HOC

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);

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>
    );
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM