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

When cloning a component using cloneWithProps and overriding ref, a warning is shown #2984

Closed
jide opened this issue Jan 30, 2015 · 8 comments

Comments

@jide
Copy link

jide commented Jan 30, 2015

The doc makes it clear that we can use cloneWithProps and pass ref in extraProps to override the ref : http://facebook.github.io/react/docs/clone-with-props.html
But when doing so, we get a warning :

var myComponent = <MyComponent ref="myref"></MyComponent>
var myClone = React.addons.cloneWithProps(myComponent, {ref: 'mycloneref'});
Warning: You are calling cloneWithProps() on a child with a ref. This is dangerous because you're creating a new child which will not be added as a ref to its parent.

Should not we get no warning in that specific case ?

Otherwise, is there a way to set the ref on myComponent after it has been created ?

@hzoo
Copy link
Contributor

hzoo commented Jan 30, 2015

Yeah, looks like the warning should be changed in that case?

@syranide
Copy link
Contributor

This is an implementation shortcoming for now, you cannot clone elements and keep the original ref, nor can you re-add it as "you" would then be the owner of it, not the original owner.

@jide
Copy link
Author

jide commented Jan 30, 2015

Hmmm I see. Ironically in my case, the owner is the same.

I read the doc again, and in fact it says how to preserve the key, but not the owner, so that's okay, but it could probably be more explicit.

So, in the end, there is no way to have an element that will, at some point, be cloned and have a ref ?

@syranide
Copy link
Contributor

So, in the end, there is no way to have an element that will, at some point, be cloned and have a ref ?

Right now, no, not that I know. But this is an implementation issue, it's not intentional.

PS. Accessing children is generally considered an anti-pattern unless they're explicitly "uncontrolled" ("controlled" components are preferable), so it's possible that you may be thinking about this the wrong way and would find using "controlled" components preferable in many ways.

@zpao
Copy link
Member

zpao commented Feb 2, 2015

@JSFB @sebmarkbage @spicyj - did we have a plan to fix this warning / expose something else?

@sebmarkbage
Copy link
Collaborator

I think that the warning is still valid, even though the owner is the same. The idea of a ref is to put a unique handle on a component. Kind of a lasso to pull in the real instance once it gets mounted in the tree. If you're overriding it, you're breaking the assumptions of the caller.

The workaround is simply to remove the ref on the original specification:

var myComponentSpec = <MyComponent></MyComponent>;
var myComponent = React.addons.cloneWithProps(myComponentSpec, {ref: 'myref'});
var myClone = React.addons.cloneWithProps(myComponentSpec, {ref: 'mycloneref'});

That way it's clear where you intended to have the ref and where you cannot rely on it.

There is a missing feature in React that we should add in the new React.cloneElement API. There is no way to preserve a ref while adding more fields.

It should be ok to clone the element without destroying the ref. We could make that possible if you don't try to override the ref field.

var myComponent = <MyComponent ref="myref"></MyComponent>
var myClone = React.addons.cloneWithProps(myComponent, {extra: 'value'});

@myagoo
Copy link

myagoo commented Feb 12, 2015

I don't see why there should be only one handle to a component instance. I don't have any solution right now but this a missing feature which can be really frustrating some times. I expect the ref property coming from a parent not to be visible inside the component.

@sophiebits
Copy link
Collaborator

@myagoo Yeah, that's one of the reasons we're looking at new types of refs so that you can get more than one handle. Some discussion at #3234. Also see #3266 which lets you change props while preserving a ref.

Closing this out.

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

7 participants