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

ref set to null on every render #11258

Closed
jharris4 opened this issue Oct 17, 2017 · 7 comments
Closed

ref set to null on every render #11258

jharris4 opened this issue Oct 17, 2017 · 7 comments

Comments

@jharris4
Copy link

Do you want to request a feature or report a bug?

Possible bug

What is the current behavior?

ref callbacks are always passed null once before subsequently being passed the reference

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template for React 16: https://jsfiddle.net/Luktwrdm/, template for React 15: https://jsfiddle.net/hmbg7e9w/).

With the attached code sample, the following life cycle functions and ref callbacks are executed:

null-ref-example.zip

/* Initial Render */
App render
MyApp render
MyPortal render
MyApp ref set to:  MyApp {…}
MyPortal ref set to:  MyPortal {…}

/* Second Render */
App will update
App render
MyApp will update
MyApp render
MyPortal will update
MyPortal render
MyApp ref set to:  null
MyPortal ref set to:  null
MyApp did update
MyApp ref set to:  MyApp {…}
MyPortal did update
MyPortal ref set to:  MyPortal {…}
App did update

What is the expected behavior?

I wasn't expecting all refs to be set to null on each render. (although it gets set again shortly thereafter)

If this is expected behaviour I didn't see it in the documentation...

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

React 16, MacOS, Chrome 61 & Safari 11.

@gaearon
Copy link
Collaborator

gaearon commented Oct 17, 2017

It is expected.
Please see #9328.

Also: https://reactjs.org/docs/refs-and-the-dom.html#caveats

screen shot 2017-10-17 at 10 36 09 pm

@gaearon gaearon closed this as completed Oct 17, 2017
@jharris4
Copy link
Author

Ahh! Thanks @gaearon , I figured this must have been somewhat by design.

It makes sense too. It's similar to how PureComponent works with inline functions.

I assumed this was specific to React 16 since this issue only manifested itself in react-bootstrap after the upgrade.

Thanks for the link to the previous issue and the caveats. Super helpful!

@joepuzzo
Copy link

@gaearon How can we solve this in a functional component? In other words because it's functional i cannot define the ref callback as a "bound" method.

@jquense
Copy link
Contributor

jquense commented May 23, 2019

@joepuzzo You can use the useCallback hook to create a stable Identify, probably better,

const [ref, attachRef] = useState(null)

return <div ref={attachRef} />

or already wrapped up: https://github.com/react-restart/hooks/blob/master/src/useCallbackRef.ts

@joepuzzo
Copy link

Hmm I like that.. however i need to set two refs in the function and just calling the setter wont be enough for me.

@joepuzzo
Copy link

To elaborate i maintain a library where i internally need to access the ref but also want to allow the user to access the ref. In order to achieve that i need to use a ref callback that looks somthing like this

(ref) => {
  userRef.current = ref;
  internalRef.current = ref;
}

@ivan7237d
Copy link

I don't get at all the part about "React needs to clear the old ref and set up the new one", but for me the workaround that did the trick was to replace ref={el => {...}} with ref={React.useMemo(() => el => {...}, [])}.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants