jehrlich
jehrlich

Reputation: 81

React component autobinding

I am new to React and javascript and trying to use moroshko's component react-autosuggest, but failing to get event handlers to bind correctly. I'm writing in coffeescript, but will paste compiled javascript too.

define [
  'jquery',
  'react',
  'reactdom',
  'autosuggest'
], (jQuery, React, ReactDOM, Autosuggest) ->
  escapeRegexCharacters = (str) ->
    str.replace /[.*+?^${}()|[\]\\]/g, '\\$&'
  getSuggestions = (praxes, value) ->
    if value == ""
      return []
    val = escapeRegexCharacters(value.trim())
    regex = new RegExp('^' + val, 'i')
    praxes.filter((prax) => regex.test(prax.species))
  getPraxSpecies = (prax) ->
    prax.species
  renderSpecies = (prax) ->
    React.createElement("span", null, getPraxSpecies(prax))

  Species = React.createClass
    getInitialState: ->
      value: ''
      suggestions: getSuggestions(@props.praxes, '')

    onChange: (event, {newValue}) ->
      @setState({value: newValue})

    onSuggestionsUpdateRequested:  ({value}) ->
      @setState {suggestions: getSuggestions(@props.praxes, value)}

    render: ->
      inputProps =
        placeholder: "Choose a species"
        value: ''
        onChange: @onChange
      autosuggest = React.createFactory Autosuggest
      React.DOM.div {key: 'autosugg', className: 'praxis'},
        autosuggest {
          key: 'autoSp',
          suggestions: @state.suggestions,
          onSuggestionsUpdateRequested: @onSuggestionsUpdateRequested,
          getSuggestionValue: getPraxSpecies,
          renderSuggestion: renderSpecies,
          inputProps: inputProps
        }
    Species

or coffeescript above compiled to javascript below:

(function() {
  define(['jquery', 'react', 'reactdom', 'autosuggest'], function(jQuery, React, ReactDOM, Autosuggest) {
    var Species, escapeRegexCharacters, getPraxSpecies, getSuggestions, renderSpecies;
    escapeRegexCharacters = function(str) {
      return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    };
    getSuggestions = function(praxes, value) {
      var regex, val;
      if (value === "") {
        return [];
      }
      val = escapeRegexCharacters(value.trim());
      regex = new RegExp('^' + val, 'i');
      return praxes.filter((function(_this) {
        return function(prax) {
          return regex.test(prax.species);
        };
      })(this));
    };
    getPraxSpecies = function(prax) {
      return prax.species;
    };
    renderSpecies = function(prax) {
      return React.createElement("span", null, getPraxSpecies(prax));
    };
    return Species = React.createClass({
      getInitialState: function() {
        return {
          value: '',
          suggestions: getSuggestions(this.props.praxes, '')
        };
      },
  onChange: function(event, _arg) {
    var newValue;
    newValue = _arg.newValue;
    return this.setState({
      value: newValue
    });
  },
      onSuggestionsUpdateRequested: function(_arg) {
        var value;
        value = _arg.value;
        return this.setState({
          suggestions: getSuggestions(this.props.praxes, value)
        });
      },
      render: function() {
        var autosuggest, inputProps;
        inputProps = {
          placeholder: "Choose a species",
          value: '',
          onChange: this.onChange
        };
        autosuggest = React.createFactory(Autosuggest);
        console.log('this: ' + this);
        return React.DOM.div({
          key: 'autosugg',
          className: 'praxis'
        }, autosuggest({
          key: 'autoSp',
          suggestions: this.state.suggestions,
          onSuggestionsUpdateRequested: this.onSuggestionsUpdateRequested,
          getSuggestionValue: getPraxSpecies,
          renderSuggestion: renderSpecies,
          inputProps: inputProps
        }));
      }
    }, Species);
  });

}).call(this);

The autosuggest component displays properly initially, accepts input, and calls onChange and onSuggestionsUpdateRequested functions in that order. State is updated, but possibly not attached to the correct component. The autosuggest then repaints exactly as initially (i.e. value='').

Substituting fat-arrow => for -> in defining onChange results in an error: Uncaught TypeError: _this.setState is not a function

I have also tried using the coding style of moroshko's example without success. Clearly, I am missing something ...

Upvotes: 2

Views: 464

Answers (1)

Brandon
Brandon

Reputation: 39202

I think the problem is in your inputProps. You need to use this.state.value:

 inputProps =
    placeholder: "Choose a species"
    value: ''
    onChange: @onChange

to:

 inputProps =
    placeholder: "Choose a species"
    value: @state.value
    onChange: @onChange

Upvotes: 2

Related Questions