Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show information from API when using search box in ReactJS?

I'm using the Star Wars API to build a React JS project. The aim of my app is to be able to search for characters.

Here is my code for the search component in the my app.

At the moment I'm able to retrieve data the API and show the information on the page but I can't work out how to show this information when it's searched for.

Any ideas?

import React, { Component } from 'react';
class Search extends Component {
  constructor(props){
    super(props)
    this.state = {
      query:'',
      peoples: [],
    }
  }

 onChange (e){
   this.setState({
     query: e.target.value
   })
  if(this.state.query && this.state.query.length > 1) {
     if(this.state.query.length % 2 === 0){
       this.componentDidMount()
     }
   }
 }

componentDidMount(){
  const url = "https://swapi.co/api/people/";
  fetch (url,{
    method:'GET'
  }).then(results => {
    return results.json();
  }).then(data => {
    let peoples = data.results.map((people) => {
      return(
        <ul key={people.name}>
        <li>{people.name}</li>
        </ul>
      )
    })
    this.setState({peoples: peoples});
    console.log("state", peoples)
  })
}

 render() {
   return (
     <form>
       <input
         type="text"
         className="search-box"
         placeholder="Search for..."
         onChange={this.onChange.bind(this)}
       />
       {this.state.peoples}
     </form>
   )
 }
}

export default Search
like image 374
helpmepie Avatar asked Jul 02 '18 10:07

helpmepie


People also ask

How do I display search results in React?

Firstly, we import useState from react . Then, we import the Scroll and SearchList components. Next, in the Search function, we use the useState hook to initialise the value of the searchField state with useState("") (an empty string). After this, we use the filter function on the details list received from the parent.

How does React js implement search API?

const searchAPI = async () => { try { const data = new FormData(); data. append("string_search", searchInput); setActivityIndicatorVal(true); let response = await fetch( "APILINK", { method: "POST", body: data, header: { "Content-Type": "multipart/form-data", }, } ); var json = await response.


1 Answers

You could put your fetch in a separate function instead of in componentDidMount and call that when the component mounts and when your query changes.

Since you might be creating multiple requests if the user types quickly, you could use a debounce to only send one request, or use something that verifies that you always use the result of the latest request, like e.g. a token.

Example

class Search extends Component {
  token = null;
  state = {
    query: "",
    people: []
  };

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

    this.search(value);
  };

  search = query => {
    const url = `https://swapi.co/api/people?search=${query}`;
    const token = {};
    this.token = token;

    fetch(url)
      .then(results => results.json())
      .then(data => {
        if (this.token === token) {
          this.setState({ people: data.results });
        }
      });
  };

  componentDidMount() {
    this.search("");
  }

  render() {
    return (
      <form>
        <input
          type="text"
          className="search-box"
          placeholder="Search for..."
          onChange={this.onChange}
        />
        {this.state.people.map(person => (
          <ul key={person.name}>
            <li>{person.name}</li>
          </ul>
        ))}
      </form>
    );
  }
}
like image 196
Tholle Avatar answered Sep 30 '22 06:09

Tholle