反应状态未相应更新

时间:2021-05-12 13:38:52

标签: reactjs

我有一个搜索组件,它根据搜索输入更新搜索结果,如果有从 API 返回的数据,则呈现为书本网格,如果没有数据,则显示一条消息,如果搜索输入为空,没有呈现任何内容。

我的问题是,当 query 状态更新时,searchResult 状态会更新,但是当我如此快速地删除搜索输入(使搜索输入为空)时,query 成为更新空字符串但 searchResult 不会根据它更新。可能是什么问题?

这是搜索组件的代码:(注意:我尝试了 componentDidUpdate() 方法和 setState() 回调函数,但没有任何效果)

import React, { Component } from "react";

// import "React Router" components
import { Link } from "react-router-dom";

// import custom components
import Book from "./Book";

// import required API
import * as BooksAPI from "../BooksAPI";

export default class BookSearch extends Component {
  state = {
    query: "",
    searchResult: [],
  };

  handleInputChange = (query) => {
    this.setState(
      {
        query: query.trim(),
      },
      () => {
        if (query) {
          console.log(query);
          BooksAPI.search(query).then((books) => {
            this.setState({ searchResult: books });
          });
        } else {
          this.setState({ searchResult: [] });
        }
      }
    );
  };

// componentDidUpdate(currentProps, currentState) {
//   if (currentState.query !== this.state.query && this.state.query) {
//     BooksAPI.search(this.state.query).then((books) => {
//       this.setState({ searchResult: books });
//     });
//   } else if (currentState.query !== this.state.query && !this.state.query) {
//     this.setState({ searchResult: [] });
//   }
// }

  render() {
    const { query, searchResult } = this.state;
    const { updateBookShelves } = this.props;
    return (
      <div className="search-books">
        <div className="search-books-bar">
          <Link to="/" className="close-search">
            Close
          </Link>
          <div className="search-books-input-wrapper">
            <input
              type="text"
              placeholder="Search by title or author"
              value={query}
              onChange={(event) => this.handleInputChange(event.target.value)}
            />
          </div>
        </div>
        <div className="search-books-results">
          <ol className="books-grid">
            { searchResult.error ? 
                <p>No results matching your search</p>
               : searchResult.map((book) => (
                  <Book
                    key={book.id}
                    book={book}
                    updateBookShelves={updateBookShelves}
                  />
                ))
              )
            ) )}
          </ol>
        </div>
      </div>
    );
  }
}

1 个答案:

答案 0 :(得分:0)

我不是 100% 确定此解决方案,因为它在其他 setState 的回调中使用 setState,但您可以尝试一下。

我认为您可能需要在调用 api 获取数据之前使用 setTimeout 以及检查 query 是否存在之前我们可以将 timeout 设置为 null 以便它不会调用不需要的 api电话。

  handleInputChange = query => {
    this.setState(
      {
        query: query.trim()
      },
      () => {
        if (this.timeout) {
          clearTimeout(this.timeout);
          this.timeout = null;
        }
        if (query) {
          this.timeout = setTimeout(() => {
            BooksAPI.search(query).then(books => {
              this.setState({ searchResult: books });
            });
          }, 800);
        } else {
          this.setState({ searchResult: [] });
        }
      }
    );
  };