简体   繁体   中英

Async issue with State in React Native

I'm trying to build a simple app that lets the user type a name of a movie in a search bar, and get a list of all the movies related to that name (from an external public API). I have a problem with the actual state updating.

If a user will type "Star", the list will show just movies with "Sta". So if the user would like to see the actual list of "Star" movies, he'd need to type "Star " (with an extra char to update the previous state).

In other words, the search query is one char behind the State. How should it be written in React Native?

  state = {
    query: "",
    data: []
  };

  searchUpdate = e => {
    let query = this.state.query;
    this.setState({ query: e }, () => {
      if (query.length > 2) {
        this.searchQuery(query.toLowerCase());
      }
    });
  };

  searchQuery = async query => {
    try {
      const get = await fetch(`${API.URL}/?s=${query}&${API.KEY}`);
      const get2 = await get.json();
      const data = get2.Search;  // .Search is to get the actual array from the json
      this.setState({ data });
    } catch (err) {
      console.log(err);
    }
  };

You don't have to rely on state for the query, just get the value from the event in the change handler

searchUpdate = e => {
    if(e.target.value.length > 2) {
       this.searchQuery(e.target.value)
    }
  };

You could keep state updated as well if you need to in order to maintain the value of the input correctly, but you don't need it for the search.

However, to answer what you're problem is, you are getting the value of state.query from the previous state. The first line of your searchUpdate function is getting the value of your query from the current state, which doesn't yet contain the updated value that triggered the searchUpdate function.

I don't prefer to send api call every change of letters. You should send API just when user stop typing and this can achieved by debounce function from lodash debounce-lodash

this is the best practise and best for user and server instead of sending 10 requests in long phases

the next thing You get the value from previous state you should do API call after changing state as

const changeStateQuery = query => {
  this.setState({query}, () => {
//call api call after already changing state 
})
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM