[DAY - 82] #3 React-router clone-coding

2023. 6. 29. 22:05·🔥 부트캠프-웹 개발 🔥/React

1) home content

 

먼저 home의 content에 출력될 데이터들을 js 파일로 만들고 export 했다.

 

export default [
    {
        id: 1,
        type : 'trip',
        thumbnail: './img/main/1.jpg',
        images: [
            { img: "https://www.tamraev.com/upload/card/20210506100948_23669410.jpg" },
            { img: "https://www.tamraev.com/upload/card/20210506100954_67067367.jpg" },
            { img: "https://www.tamraev.com/upload/card/20210506100957_08711424.jpg" },
            { img: "https://www.tamraev.com/upload/card/20210506101000_69584220.jpg" },
            { img: "https://www.tamraev.com/upload/card/20210506101003_38357467.jpg" },
            { img: "https://www.tamraev.com/upload/card/20210506101006_67372886.jpg" },
        ],
        inner: `
        <div class="content_area">
        <p class="tit1">슬기로운 전기차 여행</p>
        <p class="tit2">제주도 여행 시<br>전기차 렌트를 더 많이<br>이용하는 이유!</p>
        <div class="sns_share">
            <div class="tag">
                <span>#제주도</span><span>#탐라는전기차</span><span>#전기차</span><span>#아이오닉5</span><span>#제주도여행</span><span>#전기차렌트</span><span>#전기차렌트혜택</span><span>#렌터카</span><span>#공영주차장혜택</span><span>#주차비할인</span><span>#전기차충전혜택</span>
            </div>
            <div class="btn_area">
            <p class="tit"><img src="./img/main/icon_share.png" alt="">공유하기</p>
                    <a href="javascript:;" class="card_share blog" data-id="N" title="네이버블로그 하기"
                        onclick="click_tag('PC, MO 공통', '공유하기_블로그', '카드뉴스_#1')"><img src="./img/main/icon_blog.png"
                            alt="네이버블로그"></a>
                    <a href="javascript:;" class="card_share kakao" data-id="K" title="카카오톡 공유하기"
                        onclick="click_tag('PC, MO 공통', '공유하기_카카오톡', '카드뉴스_#1')"><img src="./img/main/icon_kakao.png"
                            alt="카카오톡"></a>
                    <a href="javascript:;" class="card_share facebook" data-id="F" title="페이스북 공유하기"
                        onclick="click_tag('PC, MO 공통', '공유하기_페이스북', '카드뉴스_#1')"><img
                            src="./img/main/icon_facebook.png" alt="페이스북"></a>
            </div>
        </div>
    </div>
        `
    },
    
    .
    .
    .
 <ul id="card_list" style={{ overflow: 'hidden', fontSize: 0, marginLeft: '-24px', height: `${cardListHeight}px` }}>
              {
                showData.map(item => <li key={item.id} onClick={() => onPop(item.id)}><img src={item.thumbnail} alt="" /></li>)
              }
            </ul>

 

그 뒤에 썸네일 사진들만 출력이 되도록 map을 사용했다.

 

home

 

2) home content 더 보기

 

more

 

더 보기 버튼의 기능을 구현하기 위해 content를 담고있는 ul의 높이를 변경해 주기로 했다.

 

<button className="btn_more" onClick={onMore}>더보기</button>

 

더보기 버튼을 누르면 onMore 함수가 실행이 되고,

 

  const [cardListHeight, setCardListHeight] = useState(400);
  const onMore = () => {
    if (cardListHeight !== 1600) {
      setCardListHeight((prevHeight) => prevHeight + 400);
    }
  };

 

if문으로 조건을 1600이 아니라면 기존의 높이값에서 400을 더한 숫자가 cardListHeight가 되도록 했다.

조건을 1600으로 하고 400씩 증가하게 한 이유는 한 줄의 content의 높이가 400이기 때문이고 총 3번 클릭을 하면 모든 content가 출력되기 때문에 더 이상 증가하지 않게 하기 위해 조건을 작성했다.

 

 

3) home content 팝업

 

popup

 

content를 클릭하면 해당 내용이 팝업으로 표시된다.

 

      {
        isPop ? <Popup currentData={currentData} offPop={offPop} /> : null
      }

 

먼저 isPop이라는 변수를 만들어 content를 클릭했을 때 true가 되어 Popup 컴포넌트가 출력되도록 했다.

그리고 클릭한 content가 무엇인지 구별하기 위해 id를 넘겨받고 find를 사용해 해당 id와 동일한 객체를 넘겨주도록 했다.

 

  const [isPop, setIsPop] = useState(false)
  const [currentData, setCurrentData] = useState('')
  const onPop = id => {
    setIsPop(true)
    setCurrentData(mainData.find(item => item.id === id))
  }
const Popup = ({ currentData, offPop }) => {
  const { images, inner } = currentData
  console.log(inner);
  return (
    <>
      <ContainerPopup>
        <div id='layer_news'>
          <div className="swiperBox">
            <Swiper
              modules={[Navigation, Scrollbar, A11y, Autoplay]}
              spaceBetween={0}
              slidesPerView={1}
              loop={true}
              pagination={{ clickable: true }}
              autoplay={true}
            >
              {
                images.map((item, idx) =>
                  <SwiperSlide><img key={idx} src={item.img} className='swiperimg' alt="" /></SwiperSlide>
                )
              }
            </Swiper>
          </div>
          <div dangerouslySetInnerHTML={{ __html: inner }} />
          <a className="btn_close" onClick={offPop}></a>
        </div>
      </ContainerPopup>
      <ContainerPopupBg />
    </>
  );
};

 

이미지의 경우 객체 안에 객체의 형태로 담겨있으므로 map을 사용했다.

 

{
        id: 1,
        type : 'trip',
        thumbnail: './img/main/1.jpg',
        images: [
            { img: "https://www.tamraev.com/upload/card/20210506100948_23669410.jpg" },
            { img: "https://www.tamraev.com/upload/card/20210506100954_67067367.jpg" },
            { img: "https://www.tamraev.com/upload/card/20210506100957_08711424.jpg" },
            { img: "https://www.tamraev.com/upload/card/20210506101000_69584220.jpg" },
            { img: "https://www.tamraev.com/upload/card/20210506101003_38357467.jpg" },
            { img: "https://www.tamraev.com/upload/card/20210506101006_67372886.jpg" },
        ],

 

 

4) home content 검색

검색

 

content 검색 기능을 추가하기 위해 form과 input을 사용했다.

 

                <form onSubmit={onSubmit}>
                  <input type="text" id="searchTxt" value={text} onChange={changeInput} placeholder="검색어를 입력해주세요." />
                </form>
  const [text, setText] = useState('')
  const onSubmit = (e) => {
    e.preventDefault();
    if (!text) return
    const filteredData = mainData.filter(item => item.inner.includes(text));
    setShowData(filteredData);
    setText('');
  }
  const changeInput = (e) => {
    setText(e.target.value)
  }

 

input에 검색 내용을 작성하면 value값을 출력해 주고, form을 submit 하게 되면 그 value값을 받아 data에서 해당 내용이 있는 객체들만 filter를 통해 배열로 만들도록 했다.

그 후 해당 배열(filteredData)을 setShowData에 넣어 화면에 출력되도록 한다.

 

              {
                showData.map(item => <li key={item.id} onClick={() => onPop(item.id)}><img src={item.thumbnail} alt="" /></li>)
              }

 

 

5) home content 타입

타입

 

인기 콘텐츠, 전기차 소개 등 메뉴를 누르게 되면 해당 메뉴에 맞는 content들이 출력되도록 했다.

우선 content data에 type를 추가해 주었다.

 

	 id: 1,
        type : 'trip',
        thumbnail: './img/main/1.jpg',
          <div className="category_menu">
            <ul>
              <li><Link className="menu_select" data-id="ALL" onClick={() => onTpye('all')}>인기 콘텐츠</Link></li>
              <li><Link className="menu_select" data-id="A" onClick={() => onTpye('info')}>전기차 소개</Link></li>
              <li><Link className="menu_select" data-id="B" onClick={() => onTpye('trip')}>슬기로운 전기차 여행</Link></li>
              <li><Link className="menu_select" data-id="C" onClick={() => onTpye('service')}>충전 및 문제 대처법</Link></li>
              <li><Link className="menu_select" data-id="D" onClick={() => onTpye('qna')}>FAQ</Link></li>
              <li><Link className="menu_select" data-id="E" to={"https://yeonhub.github.io/TP-EZtour_vanillaJS/"} target="_blank">이젠제주투어 </Link></li>
              <li><Link className="menu_select" data-id="F" to={'/noticeList'}>제주 전기차 뉴스</Link></li>
            </ul>

 

그리고 카테고리 메뉴를 클릭하게 되면 onType 함수에 어떤 타입인지 값을 넘겨주고 함수를 실행시켜 주도록 했다.

 

  const [showData, setShowData] = useState(mainData)
  const onTpye = (type) => {
    type === 'all' ? setShowData(mainData) : setShowData(mainData.filter(item => item.type === type))
  }

 

만약 넘겨받은 type이 all인 경우 전체 data를 출력해 주고 아닌 경우 filter를 통해 data.type이 일치하는 content들만 화면에 출력된다.

'🔥 부트캠프-웹 개발 🔥/React' 카테고리의 다른 글
  • [DAY - 84] context 예제, useReducer
  • [DAY - 83] context
  • [DAY - 81] #2 React-router clone-coding
  • [DAY - 80] #1 React-router clone-coding
Yeonhub
Yeonhub
✨ https://github.com/yeonhub 📧 lsy3237@gmail.com
  • Yeonhub
    비 전공자의 Be developer
    Yeonhub
  • 전체
    오늘
    어제
    • 전체보기 (169)
      • 🔍 Tech 🔍 (19)
        • Front-End (11)
        • Back-End (4)
        • AI (1)
        • Server (1)
        • Etc (2)
      • 💡 원티드 프리온보딩 챌린지 💡 (14)
        • PRE-ONBOARDING_AI (11월) (1)
        • PRE-ONBOARDING_FE (2월) (2)
        • PRE-ONBOARDING_FE (1월) (2)
        • PRE-ONBOARDING_FE (12월) (9)
      • 🔥 부트캠프-웹 개발 🔥 (118)
        • HTML5 (7)
        • CSS3 (21)
        • JavaScript (27)
        • JavaScript_advanced (9)
        • React (24)
        • Next (1)
        • MYSql (5)
        • Node (5)
        • 오늘하날(개인프로젝트) (12)
        • 이젠제주투어(팀프로젝트) (7)
      • 💻 CS 💻 (1)
        • 알고리즘 (1)
      • ⚡ 코딩테스트 ⚡ (11)
        • JavaScript (11)
      • 📚 Books 📚 (6)
        • 클린 아키텍처 (2)
        • 인사이드 자바스크립트 (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    프론트엔드 테스트코드
    expo admob
    rn bottom sheet
    expo deep linking
    react native expo fcm
    react native bottom sheet
    Node
    react native analytics
    expo fcm
    javascript fcm
    expo fcm push
    node crontab
    컴파운드 컴포넌트 패턴
    expo 지도
    expo map
    expo google map
    react native admob
    bottom sheet
    expo 길찾기
    node.js fcm
    라스콘4
    php node
    라스콘
    node fcm
    node cron
    react vite
    expo node fcm
    react native firebase analytics
    rn admob
    python node
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Yeonhub
[DAY - 82] #3 React-router clone-coding
상단으로

티스토리툴바