javascript - React 对象在两个 View 中呈现不同的效果

标签 javascript reactjs

我的 React 应用程序中有两个 View /组件,可以为用户呈现书籍。 在 ListBooks 中,它获取用户列表上的一组“书籍”,并将它们从左到右呈现在相关书架上。这工作正常。

问题出在 SearchBook 组件上。当用户输入搜索字符串时,我想从左到右显示结果而不离开屏幕。

书籍对象本身由 Book.js 组件呈现。

像这样: xxxx xxxx xxxx

我目前所拥有的是它们一个接一个地显示:

x X x

如何正确显示它?

有相当多的代码,因此我将应用程序本身放在 CodeSandBox 中以及这篇文章中的摘录。

当您导航到它时,它会给您一个错误,但只需单击沙箱浏览器 View 中的黄色选项卡,应用程序就会正常工作。 绿色按钮上的 SVG 似乎也没有渲染,但它们只是用于导航。

ListBooks.js

import React, { Component } from 'react';
import PropTypes from 'prop-types'
import './App.css'
import { Link } from 'react-router-dom'
import Book from './Book'

const shelves = [
  {
    key: 'currentlyReading',
    name: 'Currently Reading'
  },
  {
    key: 'wantToRead',
    name: 'Want To Read'
  },
  {
    key: 'read',
    name: 'Read'
  }
];

class ListBooks extends Component {

    static propTypes = {
       books: PropTypes.array.isRequired,
       onUpdateShelf: PropTypes.func.isRequired
    }

    render() {

        const { books, onUpdateShelf } = this.props

        function getBooksForShelf(shelfKey) {
          return books.filter(book => book.shelf === shelfKey);
        }

        return(
            <div className="app">
              <div className="list-books">
                <div className="list-books-title">
                  <h1>My Reads</h1>
                </div>
                <div className="list-books-content">
                  <div>
                    { shelves.map((shelf) => (
                      <div key={shelf.key} className="bookshelf">
                        <h2 className="bookshelf-title">{shelf.name}</h2>
                        { getBooksForShelf(shelf.key).length === 0 ? (
                          <div>
                            <h4>No books in this shelf</h4>
                          </div>
                        ) : (
                          <div className="bookshelf-books">
                            <ol className="books-grid">
                              <li>
                                { getBooksForShelf(shelf.key).map((book) => (
                                 <Book key={book.id}
                                     book={book}
                                     updateShelf={onUpdateShelf}/>
                                  ))}
                              </li>
                            </ol>
                          </div> 
                        )}
                      </div>
                    )) }
                  </div>
                </div>
                  <Link
                      to='/search'
                      className="open-search">
                  </Link>
              </div>

            </div>
        )
    }
}

export default ListBooks

SearchBooks.js

import React, { Component } from 'react'
import * as BooksAPI from './utils/BooksAPI'
import Book from './Book';
import { Link } from 'react-router-dom'
import PropTypes from 'prop-types'

export default class SearchBooks extends Component {

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

    static propTypes = {
      onUpdateShelf: PropTypes.func.isRequired
    }

    updateQuery(query) {
        if(query.length > 0 ) {
          this.setState(() => ({
            results: [],
            query: query
        }))
          this.bookSearch(query)
        }
        else {
          this.clearQuery()
        }
    }

    clearQuery = () => {
      this.setState({
        query: '',
        results: []
      })
    }

    bookSearch(e) {
      if (e.length > 0)
        BooksAPI.search(e)
        .then(searchResults => this.setState(currentState => ({
          results: this.updateExistingShelves(searchResults)
        })));
     }

     updateExistingShelves(searchResults) {
       if(searchResults.error !== "empty query") {
        const myBooks = this.props.books
        const addToState = searchResults.filter((result) => myBooks.find(b => {
          if(b.id === result.id) {
            result.shelf = b.shelf
            return result
          }
        }))
        myBooks.concat(addToState)
        return searchResults
       }
     }

    render() {

        const { query, results } = this.state
        const { onUpdateShelf } = this.props

        return(
            <div className="search-books">
                <div className="search-books-bar">
                  <button
                    className="close-search"
                    onClick={ this.clearQuery }>
                  </button>
                  <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>
                      { results ? (
                        results.map((book) => (
                          <Book
                            key={book.id}
                            book={book}
                            updateShelf={onUpdateShelf} 
                             />
                          ))
                        ) : (
                          <h4>No results for, "{query}"</h4>
                        )}
                    </li>
                  </ol>
                  <Link
                    to='/'
                    className="return-home">
                  </Link>
                </div>
            </div>
        )
    }
}

Book.js

import React, { Component } from 'react'
import PropTypes from 'prop-types'


class Book extends Component {

    static propTypes = {
        book: PropTypes.object.isRequired,
        updateShelf: PropTypes.func.isRequired
    }    

    render() {

        const { book, updateShelf } = this.props

        return(
            <div key={book.id} className="book">
                <div className="book-top">
                    <div className="book-cover" style={{ width: 128, height: 193,
                    backgroundImage: (book.imageLinks) ? 
                        `url(${book.imageLinks.thumbnail})`
                        : `url(${'icons/no_image_available'})` }}></div>
                        <div className="book-shelf-changer"> 
                            <select value={book.shelf ? book.shelf : 'none'} onChange={(e) => updateShelf(book, e.target.value)}>
                                <option disabled >Move to...</option>
                                <option value="currentlyReading" >Currently Reading</option>
                                <option value="wantToRead" >Want to Read</option>
                                <option value="read" >Read</option>
                                <option value="none" >None</option>
                            </select>
                        </div>
                </div>
                <div className="book-title">{book.title}</div>
                <div className="book-authors">{book.authors}</div>
            </div>
        )
    }
}

export default Book

最佳答案

所以问题实际上是CSS问题。您有一个应用于“当前阅读”部分的 list-books-content 类,该部分使用弹性框来设置内联书籍的样式。该类不适用于搜索书籍。如果您想要快速修复,只需将 display: inline-block 添加到 .book 类即可。

关于javascript - React 对象在两个 View 中呈现不同的效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50647744/

相关文章:

javascript - 在括号内使用点会破坏 swig 模板

reactjs - 如何将 jest.spyOn 与功能性 React 组件一起使用

javascript - react native : mobile number validation accept numeric value only

javascript - 在 React Router V4 中隐藏特定路线上的导航?

javascript - 在 HTML 和 Javascript 中添加网格线到背景,类似于 VisualStudios 网格

javascript - ExtJS 从 URL 获取更新进度条

javascript - 如何在 saga 中解决第一个操作后执行操作?

reactjs - React 服务器端呈现的表单在 React 组件初始化后清除输入

javascript - 如何在同一行中制作不同大小的文本

javascript - 从滚动站点的其余部分分离滚动导航栏