이번주차 클론코딩 과제로 에어비를 선택하였다.
우선 에어비앤비 헤더부분이다.
좌측에 로고, 가운데에 검색 우측에 사용자 도구들이 있다.
로고 이미지를 추출해서 이미지폴더에 넣었고, 컴포넌트 파일을 따로 만들어서 헤더 컴포넌트를 만들었다.
리액트는 이미지를 넣어주는 방법이 좀 다르다
이미지 경로를 임포트해주고 JSX파일이기 때문에 변수에 임포트된 경로를 JSX에서 사용할 수 있다.
헤더 로고에 있는 이미지의 크기를 조정해주었다.
object-fit:scale-down을 이용해 크기를 보기좋게 지종해주었다.
이후 헤더섹션 전체를 컨테니어로 지정하고 flex를 1씩 지정해줘서 세 블럭의 크기를 일정하게 지정해주었다.(2주차 피드백 내용)
서치바의 css를 어떻게해줄까 고민해봤다.
첫번째는 서치바 블록 전체를 컴포넌트로 바꿔줘봤다.
css를 전부 header.css에 해줄 예정이므로 searchbar에 props를 classname으로 하고 "search"라는 데이터를 넣어주었다.
이후 searchBar컴포넌트에서 props로 데이터를 받아 div의 classname을 넣어주었다.
하지만, searchbar 블럭보단 searchbar자체만 컴포넌트로 하는 쪽이 더 좋다고 생각했다.
Searchbar를 만들기 위해 className을 props로 전달해주었다.
searchBar를 네블록으로 나누고
큰거는 flex:2 작은칸(searchbutton)은 flex:1을 주었다.
searchbutton에 googleicon을 이용해 달아주려고 했다.
일단은 jsx 리턴문에 링크를 넣긴 했는데....이게 맞는 방법인가 잘 모르겠다.
지난 클론코딩 과제에서는 slide구현을 실패했다.
이번 react에서 carousel slide 구현에 괜찮은 라이브러리를 찾았다.
/* navslide.js */
import Slider from 'react-slick';
import "./slick.css";
import "./slick-theme.css";
import './NavSlide.css';
import Icon1 from '../img/icon/icon1.jpg'
import Icon2 from '../img/icon/icon2.jpg'
import Icon3 from '../img/icon/icon3.jpg'
import Icon4 from '../img/icon/icon4.jpg'
import Icon5 from '../img/icon/icon5.jpg'
import Icon6 from '../img/icon/icon6.jpg'
import Icon7 from '../img/icon/icon7.jpg'
import Icon8 from '../img/icon/icon8.jpg'
import Icon9 from '../img/icon/icon9.jpg'
import Icon10 from '../img/icon/icon10.jpg'
const NavSlide = ()=>{
const settings={
dots:false,
infinite:true,
speed:500,
slidesToShow:7,
slidesToScroll:2
}
return(
<div className="wrap-slider">
<Slider {...settings}>
<div className="slider-block">
<img src={Icon1}></img>
<span>A자형 주택</span>
</div>
<div className="slider-block">
<img src={Icon2}></img>
<span>섬</span>
</div>
<div className="slider-block">
<img src={Icon3}></img>
<span>해변 근처</span>
</div>
<div className="slider-block">
<img src={Icon4}></img>
<span>호숫가</span>
</div>
<div className="slider-block">
<img src={Icon5}></img>
<span>통나무집</span>
</div>
<div className="slider-block">
<img src={Icon6}></img>
<span>디자인</span>
</div>
<div className="slider-block">
<img src={Icon7}></img>
<span>초소형 주택</span>
</div>
<div className="slider-block">
<img src={Icon8}></img>
<span>국립공원</span>
</div>
<div className="slider-block">
<img src={Icon9}></img>
<span>기상천외한 숙소</span>
</div>
<div className="slider-block">
<img src={Icon10}></img>
<span>캠핑장</span>
</div>
</Slider>
</div>
)
}
export default NavSlide
navslide를 만들어주고 settings에서 간단한 설정을 구성했다.
slidesToShow는 한 슬라이드에 보여주는 총 슬라이드 갯수를 나타내고
slidesToScroll은 스크롤 시 넘어가는 슬라이드 갯수를 나타낸다.
css는 node_modules에 slick폴더에서 css파일 두개를 가져와서 내 component파일에 넣었다.
navslide의 현재 모습은 위와 같다.
에어비앤비의 mainsection을 확인해보니까 navslide에서 집의 종류를 클릭하면 그 종류에 맞는 집을 보여줬다.
어떻게 구현할지 생각해봤다.
map
함수를 사용해서 배열 렌더링일단 navslide의 이미지에 onClick이벤트를 넣어주겠다.
잘 작동하는 것을 확인할 수 있다.
이제 변수값을 설정해줘야 한다.
이 컴포넌트에서 보낼 변수는 하나이므로 useState
훅을 이용하면 될 것 같다.
import React,{useState} from 'react';
const [housenumber,setHouseNumber] = useState("number1");
useState를 임포트하고 housenumber를 설정해주었다.
default값은 number1로 해줬다.
이후 onClickimage에 setHouseNumber를 설정해줬다.
img태그에서 고유값을 사용할만한 속성이 alt밖에 떠오르지 않아서 alt를 이용하기로 했다.
onClickimage 함수의 파라메터 e의 속성인 target을 출력하면 이벤트를 실행하는 태그의 정보가 나온다.
여기서 e.target.alt를 해주면 alt값이 선택되게 된다.
이 alt값으로 useState를 통해 HouseNumber를 바꿔주었다.
이제 이 값을 집 정보가 있는 객체 배열에 넘겨주면 된다.
현재 이런 흐름으로 진행된다.
리액트는 직계 부모<->자식간 데이터 전달이 가능하다.
부모->자식간 데이터 전달은 props를 이용하면 되지만, 자식->부모는 함수를 이용해 데이터를 전달해야 한다.
app.js에 변수를 가져올 함수와 변수를 설정해주었다.
변수가 잘 오면 콘솔창에도 잘 출력될 것이다.
자식컴포넌트에서도 데이터값을 잘 전달해주었다.
잘 오는걸 확인할 수 있다.
app.js에 집의 정보 및 사진이 담긴 객체 배열을 만들어 줄 것이다.
일단 테스트를 위해 임시배열을 만들었다.
houseStyle을 통해 배열을 분류할 것이다.
getData 함수에서 클릭 변수를 받아오면 그 변수를 가지고 기존 list를 filter해서 새로운 배열을 만들어주고 그 배열을 House컴포넌트에 옮길 것이다.
House컴포넌트에 arraydata란 prop으로 mappingHouse 배열을 옮겨줬다.
지난번에도 그랬듯이, 이번에도 grid를 이용해서 css를 해줄 예정이다.
임시용 컨테이너를 만들어주고
mainsection이 app.js에 있으니까 app.css에서 위 처럼 css를 설정해줬다.
대충 전체적인 틀은 된듯.
현재 house.js의 구조는 이렇다.
houseSlide를 구현 할건데 에어비앤비는 fadeslide로 구현하였다.
위에서 사용한 slickslide에도 fade기능이 구현되어있다.
하지만, 문제가 하나 발생했다.
기존에 사용했던 Slickslide의 css를 그대로 가져오는게 문제였다.
이 문제점에 대한 해결법을 stackoverflow에서 찾았다.
HouseSlide 컴포넌트의 Slider에 class를 추가해주고
css에서 해당 클래스명에 대한 css를 작성하였다.
위아래 슬라이드가 높이가 다른 것을 확인할 수 있다.
다음은 슬라이드 상세 css다.
.slick-slider-house라는 부모 클래스를 사용하여 기존 slide와 차별을 두어 css를 수정했다.
position이 absolute니 left와 right의 수치를 조금씩 조정해주었다.
해당 버튼이 hover상태면 visibility를 다시 visible로 되게 만들었다.
여기서 하나 문제가 있었는데, 요소의 before를 hover하려면
before:hover가 아니라 hover:before로 해야한다는 것이다.
참고자료 : http://triki.net/prgm/2061
현재모습
이제 houseStyle에 맞는 객체 배열을 렌더링 해보겠다.
app.js에서 housetype이라는 변수를 받아왔으니 해당 변수를 이용해 배열 filter까진 완료하였다.
HouseData 객체 배열
HouseData를 housetype으로 filter
이 필터링된 array를 map 해서 데이터를 전달해보겠다.
이 데이터를 House 컴포넌트에서 또 하위 컴포넌트로 분류하겠다.
나같은 경우는 이미 app.js에서 모든 데이터를 분류해줬기 때문에 하위 컴포넌트에서 props 구조분해할당이 필요하지 않다.
그러나 다음부터는 객체배열 자체를 전달하고 하위 컴포넌트에서 props 구조분해할당 하는 편이 좋을 것 같다.
house컴포넌트에서 각각 역할에 맞는 변수들을 하위 컴포넌트로 보내주었다.
houseinformation에서도 데이터를 잘 전달해주고 grid를 이용해 정보창을 꾸며줬다.
정보창 모습
클론코딩 작품이라 데이터 양이 작아서 빈 곳이 좀 있다.
나중에 db연동하는법을 알면 실제 에어비앤비 사이트처럼 보이지 않을까 싶다.
React의 기본적인 기능으로 클론코딩을 시도해봤다.
기능 하나하나는 난이도가 있었지만, 기능을 파악한 후 전체적인 모습을 보니
기존의 html+css+js로 코딩하는 것보다 훨씬 편한 느낌이다.
이 페이지는 여기서 끝내지 않고 다른 기능을 배울 때마다 추가로 작성 예정이다.(22.09.02)