반응형

안녕하세요? 저번 1편에서는 데이터를 받아오고 그것을 console창에 찍어보는 것을 소개했습니다.

 

이번에는 이 데이터를 이용하여 실제 웹 페이지에 나타나도록 할 수 있게 UI를 스타일링 하겠습니다.

 

저번시간에 만들어두었던 5개의 컴포넌트들이 있었습니다.

(Header,MovieItem,MovieList,MovieInput,MovieTemplate)

 

 

우선 첫번째로 MoviTemplate 컴포넌트를 만들겠습니다.이것의 역할은 다음과같습니다.

스타일링은 styled-components로 작성합니다.

 

yarn add styled-components

로  추가해주세요

 

1.Movie app의 전체를 담아내는 컴포넌트입니다.

2.App.js에서 데이터를 받아옵니다.

3.하위 컴포넌트들(MovieItem,MovieInput...)에게 데이터를 전송하며(props)컴포넌트들을 불러옵니다.

 

 

그러면 코드로 보시죠!

MovieTemplate.js

 

import React from "react";
import styled from "styled-components";
import MovieInput from "./MovieInput"; //이 밑에 것들은 나중에 불러올것이니 아직은 작성하지 마세요.

const MovieTemplateBlock = styled.div`
  .template {
    margin: 0;
    padding: 10px;
    border: 1px solid black;
    background-color: #dfe6e9;
  }
`;

const MovieTemplate = ({
  onSubmit,
  onChange,
  input,

  date,
}) => {
  return (
    <MovieTemplateBlock>
      <div className="template">
        <MovieInput onSubmit={onSubmit} onChange={onChange} input={input} />
      </div>
    </MovieTemplateBlock>
  );
};

export default MovieTemplate;

 이런 방식으로 App.js에서 메서드나 데이터를 받아와서 아래 컴포넌트들에게 보여주는 형식입니다.

 그러면 이제 App.js에서 데이터를 보내야 작동이 될것입니다.

현재 App.js는 데이터를 받아와서 콘솔창에 찍는거 밖에 기능이 없습니다.

 

그렇기 때문에 onSubmit,onChange,input등의 데이터가 없습니다. 그것을 작성해주도록 하겠습니다.

input값은 바뀌는 값이기 때문에 state로 설정해주셔야합니다. 하지만 저희는 class컴포넌트가 아닌 함수형 컴포넌트로 작성합니다. 그렇기 때문에 useState를 react에서 불러와서 사용하겠습니다.

 

저희가 바꿀 내용은 이것입니다.

1.input,onSubmit,onChange등의 데이터와 메서드를 정의한다.

2.데이터를 받아오는 과정에서 loading이라는 state을 정의한다.

3.데이터가 받아지는 과정에서는 loading이 true, 받아 진 후에는 false로 바꾼다.

4.loading이 false라면 화면에 로딩중...이라는 화면을 보여준다.

5.onSubmit이 실행되면 input창안의 있는 값을 date라는 state에 넣어준다.

 

App.js


import React, { useEffect, useState } from "react";
import axios from "axios";
import MovieTemplate from "./MovieTemplate";

function App() {
  const [input, setInput] = useState("");
  const [date, setDate] = useState(null);
  const [loading, setLoading] = useState(false);

  const onSubmit = (e) => {
    e.preventDefault(); //새로고침 방지를 위한 작업
    if (input.length !== 8) {
      alert("8자리를 입력해주세요(ex 20200202)"); //input안에 8자리를 받기위한 코드
    }
    if (isNaN(Number(input)) === true) {
      alert("숫자만 입력해주세요"); //isNaN으로 문자열을 넣었을때 숫자를 입력해달라는 코드
    }
    setDate(input); //input안의 값을 date에 넣어줌
    setInput(""); //submit이 끝나면 input창을 비워준다.
  };

  const onChange = (e) => {
    setInput(e.currentTarget.value); 
  };

  useEffect(() => {
    const fetchMovies = async () => {
      try {
        const query = date || "20200202"; //기본값은 20200202로 하고 date가 있으면 date를 사용
        setLoading(true); //값을 받아오기 시작하면 loading을 true로 바꿔준다.
        const response = await axios.get(
          `http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=${process.env.REACT_APP_API_KEY}&targetDt=${query}`
        );
        console.log(response.data.boxOfficeResult.dailyBoxOfficeList);
      } catch (e) {
        console.log(e);
      }
      setLoading(false); //데이터 받아오는 과정이 끝나면 loading은 false로 바꾼다.
    };
    fetchMovies();
  }, [date]);

  if (loading) {
    return <div>로딩중..</div>; //로딩이 true면 화면을 로딩중이라고 보여준다.
  }

  return (
    <div>
      <MovieTemplate
        onSubmit={onSubmit}
        onChange={onChange}
        input={input}
        date={date}
      /> {/*MovieTemplate에 값을전달한다.*/}
    </div>
  );
}

export default App;

 

 

* 여기서 제가 API-KEY를 process.env.REACT_APP_API_KEY 이런 방식으로 불러온 이유는 

깃허브에 코드를 올릴때 제 코드를 남들에게 보여주고 싶지 않아서 이런 방식으로 작성하였습니다. 

이것에 대한 설명은 제 블로그에 적혀있습니다 .ㅎㅎ

penda.tistory.com/54

 

 

 

 

 

그럼 이제 두번째 컴포넌트인 MovieInput 컴포넌트를 만들어 보겠습니다.

 

MovieInput 컴포넌트의 역할은

1.input창에 날짜를 입력받는다 형식은 (YYYYMMDD) 이런 형식으로 작성되도록합니다.

2.input값이 바뀔때 마다 state값이 바뀐다.(onChange메서드로)

3.버튼을 누르거나 엔터를 입력하면 데이터를 저장합니다.(onSubmit)

4.그러면 input창 안의 값이 빈 문자열이 되도록 바꿔줍니다.

 

코드로 같이 보시죠!

 

MovieInput.js

import React from "react";
import styled from "styled-components";

const MovieInputBlock = styled.div`
  .form-input {
    display: flex;
    align-items: center;
  }
  .form-input input {
    flex: 1;
    padding: 10px;
    font-size: 1.25rem;
    transition: 0.2s linear;
    &:focus {
      transform: translateY(-5px);
      box-shadow: 2px 2px 5px black;
    }
  }
  button {
    padding: 10px;
    outline: none;
    background: none;
    color: white;
    background-color: #e74c3c;
    border: 1px solid black;
    margin: 0 5px;
    transition: 0.5s linear;
    &:hover {
      background-color: #3498db;
    }
  }
`;

const MovieInput = ({ onSubmit, onChange, input }) => {
  return (
    <MovieInputBlock>
      <div>
        <form className="form-input" onSubmit={onSubmit}>
          <input
            placeholder="날짜를입력하세요(ex)20201012)"
            value={input}
            onChange={onChange}
          />

          <button type="submit">날짜검색</button>
        </form>
      </div>
    </MovieInputBlock>
  );
};

export default MovieInput;

그러면 이제 실행시켜 볼까요??? 결과가 잘 나오나요?

 

 

 

 

결과화면)

 

MovieTemplate 결과 화면 

 


제가 공부한것들을 올리고 있습니다. 지식이 충분하지 않아서 오류가 날 수 있고 구조가 비효율적일 수 있습니다. 그렇기에 댓글로 지적은 언제나 환영입니다! 감사합니다

 

다음시간에는 실제로 입력을 받으면 list들을 보여주는 작업을 하겠습니다!

반응형

+ Recent posts