Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to forward a ref using React.Suspense and React.Lazy?

I wondering if it would be possible to use React 16's lazy, Suspense, createRef and forwardRef features together in order to attach a reference to a dynamically imported component. Does anyone know if this is possible. I tried to follow the example (https://github.com/facebook/react/pull/13446/commits/4295ad8e216e0747a22eac3eed73c66b153270d4#diff-e7eafbb41b012aba463f5a2f8fc00f65R1614), however it doesn't quite seem to work with dynamically imported components.

I have been able to get similar desired behavior by setting custom props in the parent component, passing it down to the child component and then setting the ref to that prop in the child's render function(Example below). My only issue with this approach is that it may not be the cleanest solution and it may be difficult to keep the implementation consistent across a large team. It will also make it easier when attempting to place the ref on the actual component.

// Working (Undesired implementation) // Parent.js

const LazyClass = lazy(() => { return import('./Child') };

class Parent extends React.Component {
    this.childRef = React.createRef();

    render() {
    return (
        <Suspense fallback={<div>Loading</div>}>
            <Child forwardRef={this.childRef} />
        </Suspense>
        );
    }

}

// Child.js

class Child extends React.Component {

    render() {
        return (<div>I am the Child!</div>);
    }

}

export default React.forwardRef(({forwardRef, ...props}/*, ref*/) => 
    <Child {...props} ref={forwardRef} />
);

////////////////////////////////////////////////////// // Desired Implementation with React.forwardRef()

//Parent.js

const LazyClass = lazy(() => { return import('./Child') };

class Parent extends React.Component {


    this.childRef = React.createRef();

    render() {
        return (
            <Suspense fallback={<div>Loading</div>}>
                <Child ref={this.childRef} />
            </Suspense>
        );
    }

}

// Child.js

class Child extends React.Component {

    render() {
        return (<div>I am the child</div>);
    }

}

export default React.forwardRef((props, ref) => 
    <Child { ...props } ref={ref} />
);

Setting the ref directly on a Lazily loaded component always returns null. It would be nice if it returned the value from React.createRef().

like image 889
dmscool17 Avatar asked Oct 27 '25 11:10

dmscool17


1 Answers

The "ref as a props" approach is the smaller one but as you said you have to consider prop collision. The approach you linked is still correct. The test only changed slightly:

Update: Not sure if this was a bug previously but lazy now forwards refs automatically. Just be sure you export a component that can hold a ref.

See in action: https://codesandbox.io/s/v8wmpvqnk0

like image 134
epsilon Avatar answered Oct 29 '25 00:10

epsilon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!