본문 바로가기
개발 일지(비공개)

[읽는다] React로 독서모임 Web 개발일지_02

by 2__50 2020. 6. 26.

GIT HUB https://github.com/daayooung/book_club

 

daayooung/book_club

Contribute to daayooung/book_club development by creating an account on GitHub.

github.com

 

 

book_club > src > App.js 코드

 

import React from "react";
import axios from "axios";
import Book from "./Book";
import "./App.css";

class App extends React.Component {
  state = {
    isloading: true,
    books: []
  };

  getBooks = async() => {
    const {
      data: { documents }
    } = await axios.get(
      'https://dapi.kakao.com/v3/search/book.json',{

      // 끝에 .json 을 붙힌다!
      // books.data.documents : 내가 books라고 이름지은 json정보의 .data.documents에
      // 책 검색결과가 배열 형태로 담겨있다.
      // ES6 : { data: { documents }} = ES5 : books.data.documents

      params: {
        query: '안녕',
        size: 50
      },
      meta: {
        total_count: 100,
        pageable_count: 100,
        is_end: false

        // 여러 page를 받아오고 싶은데, 아직 손을 못댔다.
        
      },
      headers: {
      Authorization: "KakaoAK da93584ea85aa1a2d72500c3bd9ed51c"
      }
    });
    console.log(documents)
    this.setState({ books : documents, isloading : false })
    
    // setState : 내가 활용할 정보를 원하는 정보, json으로 받아온 정보로 변경하여 다시
    // state에 할당
    
  }

  componentDidMount() {
    this.getBooks();
  }

  render() {
    const { isloading, books } = this.state;
    return (
      <section className="container">
        {isloading 
          ? (
          <div className="loader">
            <span className="loader__text">"도서 목록을 불러오는 중입니다."</span>
          </div>
          ) : (
            <ul className="books">
              { books.map(book => (
            <Book 
              key={book.isbn} 
              id={book.isbn} 
              title={book.title} 
              authors={book.authors} 
              publisher={book.publisher} 
              publication_date={book.datetime}
              contents={book.contents}
              price={book.price}
              bookcover={book.thumbnail}
            />       
        ))}

        {/* map : 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운
        배열을 반환 */}
        {/* https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/
        Array/map */}

            </ul>
          )}
      </section>
    )
  }
}

export default App;

 

book_club > src > Book.js 코드

 

import React from 'react'
import PropTypes from "prop-types";
import "./Book.css";

function Book ({id, title, authors, publisher, Publication_date, contents,
price, bookcover}) {
  return (
  <li className="book">
    <img src={bookcover} alt={title} title={title} />
    <div className="book__data">
      <h2 className="book__title">{ title }</h2>
      <h2 className="book__authors">{ authors }</h2>
    </div>
  </li>
  );
}

// Book component : 도서 검색 부분에 그릴 화면.

Book.propTypes = {
  id: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired,
  authors: PropTypes.arrayOf(PropTypes.string).isRequired,
  publisher: PropTypes.string.isRequired,
  publication_date: PropTypes.string.isRequired,
  contents: PropTypes.string.isRequired,
  price: PropTypes.number.isRequired,
  bookcover: PropTypes.string.isRequired
}

export default Book;

 

book_club > src > App.css 코드

 

*{
    box-sizing: border-box;
  }
  
  body {
    margin: 0;
    padding: 0;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
    Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    background-color: #f6f5f3;
    height: 100%;
  }
  
  html,
  body,
  #root,
  .container {
    height: 100%;
    display: flex;
    justify-content: center;
  }
  
  /* 이 부분의 display: flex; 때문에 도서 검색목록이 하나일 때 도서 이미지가 나타나지
  않는다. 수정 요망 */
  
  
  .loader {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: 300;
  }

 

book_club > src > Book.js 코드

 

.books {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    flex-wrap: wrap;
    padding: 50px;
    padding-top: 70px;
    width: 80%;
  }
  .books .book{
    width: 17%;
    background-color: white;
    margin-bottom: 70px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    padding: 20px;
    padding-top: 30px;
    border-radius: 5px;
    color: #220d03;
    box-shadow: 0 13px 27px -5px rgba(50,50,93,.25), 0 8px 16px -8px rgba(0,0,0,.3),
    0 -6px 16px -6px rgba(0,0,0,.025);
  }
  
  .book img {
    position: relative;
    max-width: 250px;
    width: 90%;
    box-shadow: 0 30px 60px -12px rgba(50,50,93,.25), 0 18px 36px -18px rgba(0,0,0,.3)
  }

  .book .book__title {
    margin-top: 50px;
  }

  .book .book__authors {
    opacity: 0.65;
  }
  .book h3 {
    margin-bottom: 5px;
    font-size: 24px;
    color: #2c2c2c;
  }
  
  .book .book__genres {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    margin: 5px 0px;
  }
  
  .book .book__genres li {
    margin-right: 10px;
    font-size: 14px;
  }

댓글