React onChange卡在无限循环中

时间:2018-05-24 10:46:56

标签: reactjs

我有一个React应用程序,其设置为向服务器发送API请求以检索与用户输入相匹配的书籍。

我遇到的问题是,只要任何查询开始输入搜索字段,应用就会进入循环,发送数百个请求,并且只有在从搜索中清除查询时才会停止。

如何在用户查询的每次更改中将其限制为一次调用?

import React, { Component } from 'react'
import * as BooksAPI from './utils/BooksAPI'
// import Book from './Book';

export default class SearchBooks extends Component {

    state = {
        query: '',
        books: []
    }

    updateQuery = (query) => {
        this.setState(() => ({
            query: query
        }))
    }

    clearQuery = () => {
        this.updateQuery('')
    }

    searchBook = (query) => {
        if(query.length > 0)
        BooksAPI.search(query)
         .then(books => this.setState(currentState => ({
           books: currentState.books.concat(books)
          })));
    }

    render() {

        const { query, books } = this.state
        // const { onUpdateShelf } = this.props


        const showingBooks = query === ''
        ? books
        : this.searchBook(query)

        return(
            <div className="search-books">
                <div className="search-books-bar">
                  <a className="close-search" >Close</a>
                  <div className="search-books-input-wrapper">
                    <input
                        type="text"
                        placeholder="Search by title, author or subject"
                        value={query}
                        onChange={(event) => this.updateQuery(event.target.value)}
                    />
                  </div>
                </div>
                <div className="search-books-results">
                  <ol className="books-grid">
                    <li>
                      {/* { showingBooks.map((book) => (
                       <Book
                         key={book.id}
                         book={book}
                         updateShelf={onUpdateShelf} />
                        ))} */}
                    </li>
                  </ol>
                </div>
            </div>
        )
    }
}

2 个答案:

答案 0 :(得分:1)

你的代码在这里出错。

const showingBooks = query === ''
        ? books
        : this.searchBook(query)

永远不要在API函数中进行render()调用。

相反,请在您的案例onChange函数的updateQuery中执行此操作。

在您的代码中,它会检查查询是否为空。如果不是,它实际上正在调用searchBook函数,您实际上正在设置一些state。每当state更新后,您的React Component都会调用render()函数来更新视图。现在它处于循环中,这就是你的组件陷入无限循环的原因。

答案 1 :(得分:1)

只要searchBook不是emtpy字符串,您就会使用query在渲染函数中设置状态。 setState()方法触发重新渲染,但由于您是在渲染函数内部设置状态,因此它将继续调用自身。

我不明白为什么你需要这个功能才能在渲染中。您希望在查询更改时搜索图书,但查询只能更改用户输入,因此请将函数移动到那里?这就是我要做的事情:

onChange={(event) => this.updateQuery(event.target.value)}更改为onChange={this.updateQuery}。无论如何,事件都会传递给函数。

然后,将您的bookapi逻辑移动到updateQuery函数:

updateQuery = (e) => {
  if(e.target.value.length > 0)
    BooksAPI.search(query)
     .then(books => this.setState(currentState => ({
       query: e.target.value,
       books: currentState.books.concat(books)
      })));
}