4
votes

I am trying to do a search functionality for my app, this is my first React app and don't see the advantages yet

here I have this code

let falsyData = [
    {'hello': 'greet'},
    {'Travel': 'traveling'},
    {'Heart': 'corazon'},
    {'Earth': 'tierra'},
    {'Hills': 'a name'},
    {'Blackjack': 'game'},
    {'Casino': 'gambling'}
  ];

class UniversalSearch extends Component {

  constructor() {
    super();
    this.state = {value : '', result: ''};
  } 

  render () {
    let searchRes = this._matchPeople(this.state.value),
        match = searchRes.map(function(item) {
          return <Column><Paper>{item}</Paper></Column>;
        });
    return (
      <Grid>
        <Row>
          <Column>
            <TextField onChange={this._onChange.bind(this)}
                    onKeyUp={this._changeInput.bind(this)} value={this.state.value} />
            {!!this.state.value.length &&
              <Row>
                {match}                
              </Row>
            }
          </Column>
        </Row>
      </Grid>
    );
  }

  _matchPeople = (input) => {
    let reg = new RegExp(input.split('').join('\\w*').replace(/\W/, ""), 'i');
    return falsyData.map(function(person) {
      for (let key in person) {
        if (key.match(reg)) {          
          return key;
        }
      }
    });
  }

  _changeInput = (val) => {
    let autoCompleteResult = this._matchPeople(this.state.value);    
    if (autoCompleteResult.length) {
      this.setState({result: autoCompleteResult.join(' ')});
    };
  }

  _onChange = (event) => {
    this.setState({value: event.target.value});
  }  

}

I need to search thru the falsyData array, so far here are the functions that I am implementing to search

  _matchPeople = (input) => {
    let reg = new RegExp(input.split('').join('\\w*').replace(/\W/, ""), 'i');
    return falsyData.map(function(person) {
      for (let key in person) {
        if (key.match(reg)) {          
          return key;
        }
      }
    });
  }

  _changeInput = (val) => {
    let autoCompleteResult = this._matchPeople(this.state.value);    
    if (autoCompleteResult.length) {
      this.setState({result: autoCompleteResult.join(' ')});
    };
  }

  _onChange = (event) => {
    this.setState({value: event.target.value});
  }  

my app is returning the falsyData criteria I am searching for, but is returning only the attributes and not the properties, so, how should I access to those properties?

for example: If I type hello, the hello word should be returned from falsyData and printed to the screen, which is OK, but what about if I want to printo hello with his properties which is 'greet' as you can see?

And also, I am getting that error:

Warning: Failed propType: Required prop children was not specified in Row. Check the render method of UniversalSearch.

I don't know you guys, but I've been with this for the last 3 hours, with Angular it just take | filter: and that is it.

Thanks in advance if some can help.

2

2 Answers

0
votes

You have several questions, and your code seems a bit complicated. Maybe you should try to simplify it?

I'll answer this:

I don't know you guys, but I've been with this for the last 3 hours, with Angular it just take | filter: and that is it.

If a filtered list is all you need, this should do:

// functional component without state
const FilteredList = ({things, filter}) => {
  const filtered = things.filter(t => t.search(filter) !== -1)
    return (
    <ul>
      {filtered.map(t => <li>{t}</li>)}
    </ul>
    )
}

class App extends React.Component {
  constructor ({things}) {
    super()
    this.state = {}
    this.state.things = things.split(', ')
    this.state.filter = ''
  }
  handleChange (event) {
    this.setState({filter: event.target.value})
  }
  render () {
    const things = this.state.things  // shorthands
    const filter = this.state.filter
    return (
        <div>
        <input onChange={this.handleChange.bind(this)} />
        <FilteredList things={things} filter={filter} />
      </div>
    )
  }
}

ReactDOM.render(
  <App things="asdf, lorem, and, more" />,
  document.getElementById('container')
);

jsfiddle

This is a lot more than in angular, but you now have a unidirectional flow of data (note the top-down approach, data starting inn <App>, then given to the children). This gives some extra benefits, like it's "easier" to reason about the data in your app.

Also note that except JSX and a couple {}, this is plain JavaScript. You don't need to know any special | filter or ng-repeat or ng-if or was it ng-show?

EDIT: Warning: Failed propType: Required prop children was not specified in Row. Check the render method of UniversalSearch. is probably

<Row>
  {match}                
</Row>

Here, {match} is empty.

0
votes

You are .map()ing instead of .filter()ing. You are returning a null for the map of the new object instead of removing the values.