저번에 16강, 8강, 4강, 결승전이 진행되도록 설계(?)를 끝냈었다. 이제 16강일땐 16강 텍스트가 상단에 출력되고, 8강일 땐 8강, 4강일 땐 4강이 출력되고 결승전일땐 결승전이 출력되도록 해야 했다. 4강까지는 숫자 + 강의 형태이고 결승전만 결승전이 출력되도록 하면 되는 거였고, roundOf라는 state로 몇 강인지에 대한 정보를 담고 있으니 다음과 같이 표현하기로 했다.
1) 만약 roundOf가 2라면 -> 결승전 출력
2) 2가 아니라면 -> roundOf + 강 출력
코드로는 삼항연산자를 통해 다음과 같이 작성할 수 있었다.
이제 딱 하나만 하면 된다. 바로 결승전에서 선택된 컴포넌트만 따로 출력하도록 하는 것! 기존에 2개씩 DessertItem이 출력되던 화면을 최종선택된 DessertItem 하나만 출력하는 식으로 화면에 렌더링되는 컴포넌트자체를 싹 바꿔야 하는 상황이었다. 옛날에 멋사에서 Django를 배울 땐 탬플릿 태그? 정확한 명칭은 기억 안나는데..암튼 그거를 통해 특정 조건 안에선 어떤 요소들이 보이게 하고 다른 조건에선 안 보이게 하고 이걸 처리하는 게 쉬웠는데, 리액트로는 이런 걸 어떻게 할 수 있을지 알아봤다. 즉 조건부 렌더링을 어떻게 처리할 수 있을지 고민한 것이다.
구글에 쳐서 나오는 공식문서를 참조한 결과,,황당하리만치 간단했다.
컴포넌트 작성 시 결국 return문을 사용하게 되는데, 각 조건 별로 return되는 내용 자체를 다르게 작성하는 것이다.
그래서 App.js에 다음과 같이 작성해줬다. roundOf가 1이라면, 최종선택된 컴포넌트만 보여주도록!
※ 이 외에도 삼항연산자나 논리연산자를 위한 다양한 조건부 렌더링 방법이 존재하며, 부모로부터 전달받은 prop의 값에 따라 컴포넌트에서 null을 리턴하도록 작성하는 방법 등등 다양한 조건부 렌더링 방법이 존재한다.
이제 기본적인 디자인을 입히기로 했다. 따로 css파일을 만들고 각 컴포넌트가 작성된 js파일에서 이를 import하는 식으로 쓰기로 했다. 이렇게 하면 컴포넌트별로 style태그가 만들어져서 적용되는 효과가 생긴다!
화면 최상단에 옛날에 만들어준 JofeStudio 로고를 이용해서, 이 로고를 클릭하면 내 유튜브 페이지로 이동하도록 만들었다. a태그쓰면 되는 거니까 간단히 끝날 줄 알았는데, 예기치 못한 오류에 직면했다. 나는 현재 페이지가 이동되는 게 아니라 새로운 페이지에서 유튜브 페이지가 나오길 원했기 때문에 target="_blank"를 사용했는데,
Using target=_blank without rel=noopener noreferrer is a security risk
이런 에러 메시지가 뜬 것! 구글링해보니까 이 역시 바로 해결방법이 나왔다. 우선 에러가 뜬 원인은 이렇게 하면 tabnabbing이란 피싱 공격에 노출될 수 있기 때문이라 한다. 새롭게 열린 탭에서 기존 페이지를 피싱 페이지로 바꾸는 공격이라 한다. 이를 해결하려면, a태그의 rel속성으로 "noopener noreferrer"를 줘서 해결할 수 있었다. 이 속성이 부여된 링크로 열린 페이지는 location변경과 같은 js요청을 거부한다고 한다.
※ 참고 : 리액트는 단일 URL을 가지고 SPA(single page application)으로 사이트를 표현하는 프레임워크이기 때문에 a태그 등으로 새로 페이지를 부르면 앱이 지니고 있는 상태가 초기화되고 렌더링된 컴포넌트도 모두 사라지게 된다. 따라서 리액트에서는 a태그보다는 link태그의 사용을 권한다고 한다. a태그의 href는 페이지를 이동시킬 때 페이지를 새로 불러오는 방식이라 상태 값이 유지되지 못하고 속도도 저하된다고 함..(다만 내가 지금 한 것처럼 새 탭에 띄울 때는 상관 없는 듯 하다)
결과물
'PROJECT > 개발일지' 카테고리의 다른 글
[백엔드 야생 도전일기] 스프링으로 회원가입/로그인기능 만들어보기 (2) (1) | 2023.01.28 |
---|---|
[백엔드 야생 도전일기] 스프링으로 회원가입/로그인기능 만들어보기 (1) (0) | 2023.01.27 |
[React project] EP03. 너 분명 변했다면서. 근데 왜 그대로인건데! - 리액트의 setter함수는 비동기적으로 동작한다 (0) | 2022.03.04 |
[React project] EP02. 순조로울 줄 알았던 항해의 첫 장애물 - missing dependency (0) | 2022.02.27 |
[React project] EP01. 가장 먹고 싶은 디저트 16강 웹 프로젝트를 시작하다 (0) | 2022.02.10 |