본문 바로가기

UI/React

[ React ] 포트폴리오 상세 페이지 추가하며 고민했던 문제들

포트폴리오 리뉴얼 수행하기.

포트폴리오 뉴리얼을 수행하려고 한다. 이유는 내 포트폴리오가 사람들에게
설득력이 부족한 거 같다. 하여 설득력을 높일 수 있도록 프로젝트 상세 페이지리를
넣을려고 한다.


아래는 동기부여를 만든 영상이다.
영상 URL은 맨 아래쪽

youtube : 스파르타 연구소

 

지금부터 상세 페이지를 만들면서 직면했던 문제를 어떻게 고민하고 해결했는지
간략하게 기록해보았다.

 


 

 

고민지점1. React  vs 다른 Framework
고민난이도 : ★★★★

React 일단 React를 그대로 사용하기로 했다. 이유는 React만 사용하여 서비스를 해 보는 것도
좋은 경험이라고 생각한다. 몇몇 개인 사이트는 이미 Next js를 통해서 작동하고 있다.
따라서, 일단은 React를 지속적으로 사용하면서 React만 사용할 때 직면하는 문제를
해결해 나가고 싶다.

 

고민지점2 : 데이터 관리 및 사용(DB vs zustand + 하드 코딩)
고민시간 : ★★★☆

일단 아직은 데이터가 많지 않고 빠르게 결과를 볼 수 있는 zustand + 하드 코딩하기로했다.
설득력을 높이려면 각 프로젝트마다 상세한 설명이 필요하다. 따라서 프로젝트별 상세 페이지를
제작하려고 한다. 그렇다면 상세 페이지의 데이터가 저장돼 있어야 하는데, 이것이 고민이다.
DB를 사용해서 데이터를 fetch할 수 있지만 일단은 작게 시작하는 방향으로 좀 더 빠르게
배포를 할 수 있는 사이트생각하고 있어서 zustand와 하드 코딩으로 결정했다.

 

직면 문제3 : 기존 sidbeBar의 존재, page 이동
고민시간 : ★★

기존 페이지는 한 페이지로 제작된 홈페이지이었다. 그렇기 때문에 Header라는 개념이 없었다.
상세 페이지에 Header 개념이 필요하여, 조건을 통한 랜더링 처리하기로 했다.
기존 페이지에서 일정 위치로 Scrolling DOWN을 하면 sidebar가 나오게 되어있다. 하여
특정 페이지에서는 sidebar가 없는 랜더링을 하려고 한다.
useLocation() from react-router-dom 통해서 pathname을 확인 후 if문을 통해서 조건부
랜더링으로 처리했다.

 

직면 문제4 : zustand에서 가져온 정보와 하드코딩 섞기
고민시간 : ★★★

어떻게 보면 고민지점2의 확정버전이다. 프로젝트가 그래도 몇개도니, 각 프로젝트마다
데이터가 다르다. 따라서 조건에 맞으면 이거, 이조건에 맞으면 저거를 출력할 수 있다록
처리했다.
AI가 swith로 하면 더 간결하다고 알려줘서 switch 문으로 작성했다.

 const renderingProjectContent = (project) => {
    switch (project.title) {
      case 'Project 4':
        return(
          <section 
            className='project-item-container'
            key={project.title}
            id={project.title.replace(" ", "")}
            ref={ref => projectSectionRefs.current[project.title.replace(" ", "")] = ref} // ref, projectSectionRefs 에 DOM 할당
            >
            <div className='project-item-header' >
              <h2>{project.name}</h2>
              <p>{project.type} / {project.contribution} </p>
            </div>
            {project.contents.map((item, index) => (
              <p key={index}>{item}</p>
            ))}

            <ul className="project-keywords" role='list'>
              {project.keywords.map((library,index) => (
                <li key={index}> {library}</li>
              ))}
            </ul>

            <div className='project-live-container' >
              <Link className='project-live' to={project.url} target='_blank'>읽어보기</Link>
              {
                project.popup && project.popup.map((item,index)=>{
                  const [key, value] = Object.entries(item)[0]
                  return(
                    <Link key={index} className='project-live' to={value} target='_blank'>{key}</Link>
                  )
                })
              }
            </div>
            <div className='project-item-inner-container' >
              <h3>직면한 문제</h3>
              <dl>
                <dt>1. 결제 테스트, CORS</dt>
                <dd>과제 : 로컬 환경에서 결제 테스트 시 브라우저 Same-Origin Policy에 의하여 막힘 발생</dd>
                <dd>
                    {/* 문제 해결 : <br />
                    처음에는 서로 시간이 맞지 않아서 먼저 테스트해보기 위해 ngrok 프록시를 통해 우회 시도. 하지만 ngrok 데이터를 모두 사용하여 결국 날짜를 정하고 서버에서 제 IP 주소를 허용 */}
                </dd>
                <dd>토스 결제 시스템 연동 중 CORS 문제 발생, 먼저 ngrok를 활용하여 팀과의 개발 가능 시간 차이를 해소하고 서버 연동 후 문제 해결</dd>
                <figure>
                  <img
                      src='/pudding_CORS.png'
                      alt='페이먼트 대기 화면'
                  />
                  <figcaption>CORS 에러 해결 과정 이미지</figcaption>
                </figure>
                {/* <dd>결과 : 토스 결제 테스트 가능</dd> */}
              </dl>

              <dl>
                <dt>2. 결제 시, 데이터 연결 시간차</dt>
                <dd>과제 : 토스에서 전달하는 데이터 불완전성 (데이터 연결 시간 지연)</dd>


...중략...

        case 'Project 3':
          return(
            <section 
              className='project-item-container'
              key={project.title}
              ref={ref => projectSectionRefs.current[project.title.replace(" ", "")] = ref} // ref 설정
            >
            <div className='project-item-header' >
              <h2>{project.name}</h2>
              <p>{project.type} / {project.contribution} </p>
            </div>

... 중략 ...

            <div className='project-item-inner-container' >
              <h3>직면한 문제</h3>

              <dl>
                <dt>1. DB를 한번도 설계해본 경험이 없어</dt>
                <dd>과제 : DB 세팅</dd>
                {/* <dd>
                    문제 해결 : <br />
                    Supabase를 통해 DB를 설계하기 위해 생활코딩 강의부터 4개 이상의 YouTube 영상을 참고하며 독학. DB 설계 시 AI의 도움을 받았으며, Supabase API를 통해 연동.
                </dd> */}
                <dd>빠르고 간편하게 DB를 구축하고자 Supabase를 활용하여 DB 환경 구성</dd>
                <figure>

                <img
                  src='/supabase_DB.png'
                  alt='좀쉼쉼 DB table'
                  />
                  <figcaption>좀쉼쉼 DB 테이블 이미지</figcaption>
                  </figure>
                {/* <dd>결과 : Supabase를 통해 DB 세팅 완료. user, accommodation, reservation 3개의 테이블을 중심으로 서비스 작동</dd> */}
              </dl>



// return(
...
   <section> { projects.map(project => renderingProjectContent(project)) } </section>
...

)

 

 

 

코드를 작성하면서, 처음 React 할 때, 작성했던 문장들을 보면서
그래도 많이 발전했던 모습들을 볼 수 있었다.

나중에 기회가 되면 Node js를 통해서 포트폴리오 사이트를 리뉴얼해봐야겠다.

 

 

참조

https://www.youtube.com/watch?v=2BcfL5u7c1I