如何在HOC中访问已包装组件的div元素

时间:2020-03-11 10:58:24

标签: javascript reactjs higher-order-components react-ref

我尝试了许多不同的语法,但无法完成这项工作。我正在尝试在HOC中访问包装的组件的div元素,以便可以使用它来初始化我的Google Map实例,该实例需要一个HTML节点作为第一个参数。我没有使用类组件。据我了解,我需要在子组件中创建ref并在HOC中创建forwardRef。但是我也尝试过相反的方法,但是没有运气。我当前的代码如下:

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

包装好的组件:

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

1 个答案:

答案 0 :(得分:3)

好的,我知道了。问题是我在HOC中收到引用,而我应该在包装的组件中这样做。我会说React.forwardRef有点误导性。

由于在HOC中,NewComponent基本上是指我们用HOC包装它的任何组件,因此我们可以在此HOC新返回的组件中使用useRef钩子来创建引用,并引用我们的OriginalComponent。现在,如果我们不转发引用,它将仅引用组件本身,而不引用组件内部的div。因此,在包装的组件Map.js中,我们需要使用React.forwardRef(props, ref)捕获此引用,最后将引用设置为return语句<div className="map" style={mapStyles} name={name} ref={ref} ></div>内部的div元素。

完整示例:

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

原始包装的组件:

const Map = React.forwardRef((props, ref) => {
    const { name } = props;
    useEffect(() => {
    }) 
    return (
        <div>
            <div className="map" style={mapStyles} name={name} ref={ref} ></div>
        </div>
    );
});