I wanted to drop my string-based refs bindings and replace them with callback-based ones, however, when I tried to replace ref="email"
with ref={ (ref) => this.refs.email = ref }
, I received an error: TypeError: Can't add property email, object is not extensible
.
I didn't find any informations about this in docs, but I found other issue in which @frederickfogerty did what I tried to do: ref={ c => this.refs['wrapper'] = c }
... and I assume that back in 22 Sep 2015 it worked, now it doesn't. Did something change and refs object became nonextensible? Is assigning refs manually through callbacks to this.refs
considered a bad practice now?
AFAIK this was never good practice or recommended. Just store it directly on the instance (this
).
@syranide Can you elaborate? I don't really see how does storing references differs between the this.refs.email
/this.email
/this.dom.email
/...
variants, they are all stored within the instance.
@biphobe this.refs
is a frozen object. Assign your references to this
directly.
@biphobe scrolling down in that issue it says that you can't assign to refs, so it didn't work back then either. Sorry for the confusion, I will edit my comment on that issue.
@frederickfogerty You're right, I omitted the bottom half of the comments when scanning the issue, sorry.
Thanks for replies, @syranide, @satya164.
Please provide an example reproducing this.
@gaearon
_Please provide an example reproducing this._
Here is example that throws very same error
Docs https://reactjs.org/docs/uncontrolled-components.html
// I create ref here as in React docs
constructor(props) {
super(props);
this.first_name = React.createRef(); // as in docs
}
render() {
return(
<View style={{marginVertical: 10}}>
<TextInput
required={false}
autoFocus={false}
ref={ this.first_name } // Then I provide my ref here
keyboardType={'default'}
placeholder={'Your first name'}
defaultValue={ personal.first_name }
/>
</View>
)
}
And I get this:
Environment:
System:
OS: macOS High Sierra 10.13.4
Binaries:
Node: 8.11.3 - /usr/local/bin/node
npm: 5.6.0 - /usr/local/bin/npm
Browsers:
Chrome: 68.0.3440.106
Safari: 11.1
npmPackages:
"react": "16.3.0-alpha.2",
"react-apollo": "^2.1.1",
"react-native": "0.54.2",
"react-native-svg": "^6.3.1",
"react-native-svg-icon": "^0.7.0",
"react-native-vector-icons": "^4.5.0",
"react-navigation": "^1.5.8",
You can unfreeze this object by reassigning it in componentWillMount
:
componentWillMount() {
this.refs = {}
}
@wzup were you able to figure out a workaround?
Facing the same issue . @wzup - let me know if you resolved the issue
TypeError: Cannot add property value, object is not extensible
Code -
constructor(props) {
super(props);
this.query = React.createRef();
}
handleSearch(event) {
event.preventDefault();
if (this.query.value !== null && this.query.value !== '') {
console.log("query",this.query.value);
this.props.dispatch(searchMediaAction(this.query.value));
this.query.value = '';
}
}
<input
type="text"
ref={this.query}
/>
@vishwa3 you need to use this.query.current.value
, not this.query.value
@vishwa3 you need to use
this.query.current.value
, notthis.query.value
@satya164 :Thanks
The current
doesn't trigger a re-render though. I'm trying to pass a mutable variable from the parent that, when changed in the child, updates the parent's value too (I'm pretty sure this is generally a bad idea, but I need to do this for some reason for an interview code challenge. lol)
@vishwa3 you need to use
this.query.current.value
, notthis.query.value
This answer should be pinned above 馃憤
Most helpful comment
@vishwa3 you need to use
this.query.current.value
, notthis.query.value