0

I need to create a menu in Reactjs and call an API using redux to display the data. Now I want to create a search box in the menu to display a particular category. I have tried using refs but it doesn't work. And I guess it is deprecated.

class App extends Component {
  constructor(props){
  super(props);
  this.state = { datas: []}//props.menu_items 
}

componentWillMount() {
 this.setState({
  datas : require('./sample2')
 });
}

render() {
 return (
  <div className="App">
    <h2>Menu Dashboard</h2>
    <Buttons />
    <div style={{ border:'1px solid 
  #E7E7E7',marginTop:'3%',width:'90%',marginLeft:'5%'}}>
     <Filters />
     <DisplayTable datas={this.state.datas}/>
    </div>
  </div>
   )
  }
  }
  class Buttons extends Component {
   constructor(props){
   super(props);
   // this.state = {searchInput: ''};
   this.search = this.search.bind(this);
  }
  search(event){
   if (event.keyCode === 13) {  
   // this.setState({searchInput: event.target.value});
   console.log(this.refs.searchInput.value);
   event.preventDefault();
   }
  }
  render() {
    return (
     <div>
     <button className="button1">Categories</button>
     <button className="button2">Add Ons</button>
     <FormControl type="text" placeholder="search items"  ref="searchInput"  
     className="search " onKeyDown={this.search} />
     </div>
    )
   }
  }

How should I access the value entered in the search box so that I can display the data according to it? Also, I want to call the search function by pressing enter. I have tried the above code for both. Thanks in advance.

sugandh_g
  • 357
  • 2
  • 7
  • 16

3 Answers3

0

You can try below code, I used name for search item you can replace with it searchInput.For redux action search you need to create a search action within that you can call the api and can store that data into props.

import React from "react";
import {connect} from "react-redux";
import {SearchItems} from "../actions/SearchAction";

/**
 * Search Item Class
 */
class Search extends React.Component {
  /**
   * Constructor
   * @param props
   */
  constructor(props) {
    super(props);
    this.state = {
      name: ""
    }
  }

  /**
   * Set the search text data into the state object
   * @param event
   */
  searchByText = (event) => {
    this.state[event.target.name] = event.target.value;
    this.props.SearchItems(this.state);
  }

  /**
   * Render the Search filter options.
   * @returns {XML}
   */
  render() {
    return (
       <div className="col-md-8 pull-left">
              <div className="form-group form-control-by-1">
                <input type="text" className="form-control-search search-input-box" id="name" name="name" value={this.state.name} onChange={(e) => this.searchByText(e)} placeholder="Search "/>
              </div>
            </div>
    );
  }
}

/**
 * Call the Search action function with search data.
 * @param dispatch
 * @returns {{SearchItems: (function(*=))}}
 */
const mapDispatchToProps = (dispatch) => {
  return {
    SearchItems: (inputData) => {
      dispatch(SearchItems(inputData));
    }
  };
};


/**
 * attach  both Reducer and Action into the Search component.
 */
export default connect(mapDispatchToProps)(Search);
mohan rathour
  • 420
  • 2
  • 12
  • Now wherever I want to display this search box , I call this.props.Search?I am learning redux so i do not know much – sugandh_g Jul 05 '17 at 06:10
  • No, The search function will handle it, whenever you search something it will automatically trigger that function – mohan rathour Jul 05 '17 at 07:03
0

The ref searchInput is the reference of FormControl component, not of the input component. The FormControl is not storing the value of input in its reference.

Instead, pass an onChange handler to the FormControl component and store the value of input in your state like this:

onChange = e => {
  this.setState({ value: e.target.value })
}

and modify your search function to this:

  search = e => {
    if (e.keyCode === 13) {
      console.log('this.state.value..', this.state.value)
    }
  }

Render your FormControl like this:

<FormControl value={this.state.value} type="text" placeholder="search items" 
                   className="search " onChange={this.onChange} onKeyDown={this.search} />
Ritesh Bansal
  • 3,108
  • 2
  • 16
  • 23
  • Thanks , it works fine but whenever I press enter after typing in a word it shows --Cannot read property 'state' of null. search G:\menu-services\menu\src\components\map\presentational\map.js:110 107 | } 108 | search(e) { 109 | if (e.keyCode === 13) { > 110 | console.log(this.state.searchString); 111 | } 112 | } 113 | render() { – sugandh_g Jul 05 '17 at 05:43
  • I don't think there should be any error as per above code. Try binding ` this.search = this.search.bind(this)` in constructor. – Ritesh Bansal Jul 05 '17 at 05:48
0

According to the documentation, FormControl assigns a ref to child input element, when you pass with the prop name inputRef.Also React docs suggest on using the callback approch for refs over the string refs.

See this answer for more info:

In React .js: is there any function similar like document.getElementById() in javascript ? how to select certain object?

So you can assign the ref and get the value like

class Buttons extends Component {
   constructor(props){
   super(props);
   // this.state = {searchInput: ''};
   this.search = this.search.bind(this);
  }
  search(event){
   if (event.keyCode === 13) {  
   console.log(this.searchInput.value);
   event.preventDefault();
   }
  }
  render() {
    return (
     <div>
     <button className="button1">Categories</button>
     <button className="button2">Add Ons</button>
     <FormControl type="text" placeholder="search items"  inputRef={(ref) => {this.searchInput=ref}}  
     className="search " onKeyDown={this.search} />
     </div>
    )
   }
  }
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400