React: Refs - "object is not extensible"

Created on 28 Jun 2016  路  14Comments  路  Source: facebook/react

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?

Most helpful comment

@vishwa3 you need to use this.query.current.value, not this.query.value

All 14 comments

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:

screen shot 2018-09-17 at 3 40 49 pm

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, not this.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, not this.query.value

This answer should be pinned above 馃憤

Was this page helpful?
0 / 5 - 0 ratings