0

I have following component in my React Project. What I want to do is to Add a className attribute to the <li> element. Set it equal to the return value of the getSortByClass() method and pass in sortByOptionValue as the argument.

import React from 'react';
import './SearchBar.css';

const sortByOptions = {
  'Best Match': 'best_match',
  'Highest Rated': 'rating',
  'Most Reviewed': 'review_count'
}
function getSortByClass(sortByOption){
  if (this.state.sortBy === sortByOption) {
    return 'active';
  }
  else {
    return '';
  }
}
function handleSortByChange(sortByOption){
  this.setState({
     sortBy: sortByOption
   });
}
export class SearchBar extends React.Component{
    renderSortByOptions(){
      return Object.keys(sortByOptions).map(sortByOption => {
        let sortByOptionValue = sortByOptions[sortByOption];
        return <li className={getSortByClass(sortByOptionValue)} key={sortByOptionValue}> {sortByOption} </li>;
      });
    }

    constructor(props) {
        super(props);
        this.state = {
          term: '',
          location: '',
          sortBy: 'best_match',
        };
    }
    render(){
      return (
      <div className="SearchBar">
        <div className="SearchBar-sort-options">
          <ul>
            {this.renderSortByOptions()}
          </ul>
        </div>
        <div className="SearchBar-fields">
          <input placeholder="Search Businesses" />
          <input placeholder="Where?" />
        </div>
        <div className="SearchBar-submit">
          <a>Lets Go</a>
        </div>
        </div>
      );
    }
  }

  export default SearchBar;

I am getting error: TypeError: Cannot read property 'state' of undefined after setting the classname field.

1 Answer 1

4
....
function getSortByClass(sortBy, sortByOption){
  if (sortBy === sortByOption) {
    return 'active';
  }
  else {
    return '';
  }
}

export class SearchBar extends React.Component{
    handleSortByChange = (sortByOption) => this.setState({ sortBy: sortByOption});

    renderSortByOptions(){
      const that = this;

      return Object.keys(sortByOptions).map(sortByOption => {
        let sortByOptionValue = sortByOptions[sortByOption];
        return <li className={getSortByClass(that.state.sortBy, sortByOptionValue)} key={sortByOptionValue}> {sortByOption} </li>;
      });
    }
    ....

Pass your state to the getSortByClass method as it doesn't have access to this because it is written outside the class. Also write handleSortByChange inside your class as it is accessing setState from this.

Also you can beautify the code as :

renderSortByOptions(){
          const that = this;

          return Object.keys(sortByOptions).map(sortByOption => {
            let sortByOptionValue = sortByOptions[sortByOption];
            return (
               <li className={that.state.sortBy === sortOption ? 'active' : ''} 
                   key={sortByOptionValue}
               > 
                   {sortByOption} 
               </li>
           );
        });
     }
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you @Ajay Gaur. but I am not still getting the class name active while clicking on the list item.
Well that's a separate issue. Try debugging that. See if the values you're equating for are equal or not

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.