[React] 넷플릭스 클론코딩 (3)

노유성·2023년 5월 8일
0
post-thumbnail

⭐styled components

🪐styled components란

Styled Components는 React 애플리케이션에서 스타일링을 쉽게 관리할 수 있게 해주는 라이브러리입니다. 이 라이브러리는 JavaScript 코드로 스타일을 작성할 수 있기 때문에 CSS 파일이 필요하지 않으며, CSS-in-JS 방식으로 스타일을 관리할 수 있습니다.
-chatGPT

🪐라이브러리 다운로드

npm install styled components

🌈에러 해결

npm ERR! Cannot read properties of null (reading 'edgesOut')
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\shdbt\AppData\Local\npm-cache_logs\2023-05-08T01_09_13_668Z-debug-0.log

이라는 에러가 발생했다. 정확히 무슨 에러인지는 모르겠지만.. 2가지 해결법이 존재했다.

  1. 파일 경로에 영문자, 숫자, _ 를 제외한 문자가 있는지 확인하기
  2. npm install --legacy-peer-deps --save styled-components
    로 재설치하기

2번으로 수행하니 일단 import가 안 되는 문제는 해결됐다.

🪐예제

import styled from "styled-components"

const Container = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  width: 100%
  height:100vh
`;

위처럼 모듈을 가져온 후, 모듈 내에 정의된 태그를 이용해서 스타일링된 태그를 반환받아서 컴포넌트로 활용한다. 이렇게 사용한다면 가장 밑단에 존재하는 태그들 중 반복되는 태그들을 컴포넌트로 만들어서 사용할 수 있으니 훨씬 더 직관적이다.

다른 컴포넌트들과 마찬가지로 props를 받아서 사용할 수 있다.

import styled from 'styled-components';

const Button = styled.button`
  background-color: ${props => props.bgColor || '#ffffff'};
  color: ${props => props.textColor || '#000000'};
  border: none;
  padding: 10px 20px;
`;

function App() {
  return (
    <div>
      <Button>Default</Button>
      <Button bgColor="#00ff00" textColor="#ffffff">
        Green
      </Button>
      <Button bgColor="#0000ff" textColor="#ffffff">
        Blue
      </Button>
    </div>
  );
}

export default App;

⭐Iframe

🪐Iframe이란

iframe(inline frame)은 HTML에서 다른 HTML 문서나 웹 페이지를 포함하는 태그입니다. 즉, iframe 태그를 사용하면 현재 웹 페이지 안에 다른 웹 페이지를 삽입할 수 있습니다.
-chatGPT

🪐예제


유투브에 가면 "공유"버튼이 있다. 해당 버튼을 클릭하면

이런 화면이 나오는데 여기서 퍼가기(embed) 버튼을 클릭하면

동영상을 버가는 부분에서 iframe 태그를 발견할 수 있다.

태그 안에서 속성을 적절히 조절하여 화면에 다른 html 화면을 띄울 수 있다.

⭐비디오 배너 생성하기

🪐state

 const [isClicked, setIsClicked] = useState(false);

버튼이 클릭되었는 지에 대한 여부를 보여주는 State이다.

그래서 특정 버튼이 선택되면

<button className='banner__button play' disabled={!!!movie?.videos?.results?.length ?? 1} onClick={() => setIsClicked(true)}>play</button>

isClicked를 true로 만들어주는 리스너를 등록한다.

🪐return

isClicked의 값을 가지고 어떤 화면을 보여줄 것인지 if-else문을 구성한다

if (!isClicked) {
    return (
      "일반 UI"
    )
  } else {
    return (
      "버튼이 클릭된 후, 동영상을 보여주는 UI"
    )
  }

이렇게 구성을 하면 버튼이 클릭되는 순간 state값이 변하며 컴포넌트가 리렌더링이 되며 조건문을 통과하면서 상황에 맞는 화면을 보여줄 수 있다.

🪐동영상 보여주기

else {
    return (
      <Container>
        <HomeContainer>
          <iframe
            width="640"
            height="360"
            src={`https://www.youtube.com/embed/${movie.videos.results[0].key}?controls=0&autoplay=1&loop=1&mute=1&playlist=${movie.videos.results[0]}`}
            frameBorder="0"
            allow="autoplay; fullscreen"></iframe>
        </HomeContainer>
      </Container>
    )
  }

버튼이 클릭되었을 경우 보여주는 화면이다.
Container, HomeContainer는 styled component이며 기본적인 배경화면을 구상한다.

주목할 점은 iframe 태그에서 src 속성이다. 코드를 보면 주소를 template literal로 구성했다.
이전에 만들었던 state 변수인 movie 내에 있는 property 중에 해당 영상의 주소를 담은 key값이 있다.
그 key값을 이용해서 유투브에서 영상을 가져온다.

🪐추가 내용

하지만 어떤 영화는 영화를 소개하는 영상이 없을 수도 있고 그럴 경우에는 movie.videos.results 속성이 존재하지 않는다. 즉 undefined이다.
해당 경우에 위처럼 코드를 작성하게 되면은 undefined를 참조하려는 참조에러가 발생한다.

해당 에러를 막아주기 위해서

play버튼을 만약에 영화 속성이 존재하지 않는다면 비활성화를 하도록 코드를 구성했다.

UI를 구성하는 부분 중 위 play 버튼을 담당하는 UI요소는

<button className='banner__button play' onClick={() => setIsClicked(true)}>play</button>

이다.

여기서 버튼에 disabled 속성을 추가했다.

disabled={!!!movie.videos?.results?.length ?? true}

먼저 optional chaining을 이용해서 참조하려는 property가 undefined일 경우 에러를 발생하지 않고 undefined를 반환하도록 작성했다.

!! 연산자를 이용해 length 값을 boolean으로 변환하였고 만약에 length가 1 이상 이라면 true를 반환한다. 하지만 값이 존재하면은 disabled=false이어야 하므로 not 연산자를 하나더 추가해서 비디오가 있으면 버튼을 활성화하고, 비디오가 없으면 null 병합 연산자에 의해 true가 반환되어 버튼을 비활성화하였다.

disabled 속성을 추가해서 undefined를 참조할 때의 참조에러를 방지하고 또 비디오가 없다면 버튼을 비활성화하는 기능을 추가했다.

🌌정리하며

왜 버튼에 이벤트 리스너를 등록하여 화면을 보여주지는 않았는 지에 대해서 생각을 해보면, 버튼을 클릭했을 때 화면의 state를 변화시키는 것은 해보았어도 화면에 새로운 내용을 추가하는 것은 배우지 않았다. 그래서 이벤트 리스너로 setter 함수를 넘겨주는 것이 화면 전환을 하는 간단한 방법 중 하나가 아닌가싶다.

또한, state를 이용하면 동영상 시청을 마치고 다시 메인화면으로 돌아올 때도 같은 컴포넌트 내에 존재하는 if-else문 이기에, setter 함수를 통해서 isClicked의 값만 바꿔준다면 간단히 메인화면으로 돌아올 수 있다는 장점도 있다.

같은 기능을 구현하는데에 하나의 로직만이 존재하는 것이 아니라 많은 로직이 존재하고 어떤 경우에는 어떻게 로직을 짜는 것이 더 효율적인지 생각을 해보고 또 나중에 내용을 추가하거나 변경할 일이 있을 때 간단하게 바꿀 수 있도록 구성하는 것이 중요한 것 같다.

profile
풀스택개발자가되고싶습니다:)

0개의 댓글