Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React ref doesn't work with dynamically imported components #2842

Closed
1 task done
brandones opened this issue Aug 24, 2017 · 6 comments
Closed
1 task done

React ref doesn't work with dynamically imported components #2842

brandones opened this issue Aug 24, 2017 · 6 comments

Comments

@brandones
Copy link

  • I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior

When creating a callback reference to a dynamically imported component, the reference should resolve to the component as if it had been imported normally.

Current Behavior

The ref behaves strangely. The reference to the component doesn't seem to have any of the attributes or state of the component -- all undefined.

Steps to Reproduce (for bugs)

Here's a nice smallish example. Bring your own boilerplate components/page.js

pages/refs.js

import React, { Component } from 'react'
import dynamic from 'next/dynamic'
import Page from '../components/page'

const Child = dynamic(
  import('../components/child')
)

class Parent extends Component {

  onSubmit = () => {
    console.log(this.child.state.value)  // undefined
    console.log(this.child.getValue())  // throws
  }

  render() {
    return (
      <div>
        <Child ref={ (child) => { this.child = child } } />
        <button onClick={ this.onSubmit }>Submit</button>
      </div>
    )
  }
}

export default class extends Page {
  render() {
    return <Parent />
  }
}

components/child.js

import React, { Component } from 'react'

export default class extends Component {
  constructor(props) {
    super(props)
    this.state = {
      value: 23
    }
    this.getValue = () => String(this.state.value)
  }
  render() { return <div>{this.state.value}</div> }
}

Context

I'm trying to create a wrapper around a wrapper around React-RTE. The first layer wrapper has a getValue() method one can use to extract the transformed value from React-RTE. The transformation is non-trivial and kind of expensive, so it makes sense to do it on-demand, and the component that should demand it is in the second-layer component. The first layer wrapper needs to be loaded dynamically (with SSR disabled).

Your Environment

Tech Version
next 3.0.6
node 6.9.1
OS macOS 10.12.6
browser Chrome 60.0.3112.90 (Official Build) (64-bit)
@pencilcheck
Copy link
Contributor

The component imported is actually all instances of "DynamicComponent" for me, thus all refs are not working.

@jsvde
Copy link

jsvde commented Dec 19, 2017

Dynamically imported Components are wrapped in a DynamicComponent. Since React does not allow forwarding ref maybe you could substitute ref for innerRef like styled-components[#102]

@timneutkens
Copy link
Member

There's a new API coming in future React that allows to pass off ref.

@ritz078
Copy link

ritz078 commented Mar 27, 2018

Any hack for now?

@paschaldev
Copy link

Seriously need a hack

@zhongyuanjia
Copy link

I use this to get ref

class Example extends React.Component {
  constructor() {
    this.state = {
      DynamicComponent: null,
    };
    this.refCom = React.createRef();
  }

  render() {
    const {DynamicComponent} = this.state;
    return DynamicComponent && <DynamicComponent ref={this.refCom}/>
  }

  componentDidMount() {
    import("my-dynamic-component")
      // if your component use export default, use val.default,
     // else use val[yourComponentName]
    .then(val => this.setState({DynamicComponent: val.default}));
  } 
}

@lock lock bot locked as resolved and limited conversation to collaborators Apr 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants