일기프로젝트에서 내가 해결한 문제들! (feat. 마크업을 잘하자!)

신은수·2023년 10월 26일
0

기타

목록 보기
5/5
post-thumbnail

1. Duplicate ID

1) 문제상황

  • 일기 등록 폼에서 기분선택 버튼을 누를 시 정상적으로 작동하지만, 일기 수정 폼에서 기분 선택 버튼을 누를 시 일기 등록 폼의 기분 선택 폼이 작동하는 문제가 일어났습니다. ezgif-1-93e40ed061
  • 문제 코드
    ```jsx
    // ./src/components/home/DiaryFormContent.tsx
    <fieldset className={styles['button-group']}>
    	  <legend className="a11y-hidden">오늘의 당신의 기분을 선택해보세요</legend>
    	  {Object.entries(feelingData).map(([key, value]) => (
    	    <div key={value} className={styles['btn-feeling']}>
    	      <input
    	        name={`feeling`}
    	        id={`${key}`}
    	        type="radio"
    	        className="a11y-hidden"
    	        value={key}
    	        onChange={onChange}
    	        required
    	      />
    	      <label htmlFor={`${key}`} className={key === inputs.feeling ? styles.checked : ''}>
    	        <span>{value}</span>
    	      </label>
    	    </div>
    	  ))}
    </fieldset>
    ```

2) 문제해결

  • 문제를 해결하지 못하고 다른 것을 코딩하다가 html markup validator를 돌리게 되었습니다. Duplicatie ID rainbow 라는 에러가 나온 것을 확인하게 되었습니다. HTML 문서에는 하나의 고유한 ID만 존재해야하는데, 일기등록폼의 기분선택 버튼과 일기수정 폼들의 기분선택 버튼들이 동일한 ID를 갖고 있기 때문에 해당 문제가 발생한다는 것을 깨닫게 되었습니다.

  • 문제 해결 코드1

    // ./src/components/home/DiaryForm.tsx
    ...
    <DiaryFormContent inputs={inputs} onChange={onChange} suffix={'add'} />
    
    // ./src/components/home/DiaryItem.tsx
    ...
    <DiaryFormContent onChange={onChange} inputs={inputs} suffix={'edit'} />
    
    // ./src/components/home/DiaryFormContent.tsx
    ...
    <>
    	<input
    	  name={`feeling`}
    	  id={`${suffix}${key}`}
    	  type="radio"
    	  className="a11y-hidden"
    	  value={key}
    	  onChange={onChange}
    	  required
    	  />
    	<label htmlFor={`${suffix}${key}`} className={key === inputs.feeling ? styles.checked : ''}>
    	  <span>{value}</span>
    	</label>
    </>
    • 일기 등록 폼과 일기 수정 폼의 id를 다르게 하기 위해 접미사(일기 등록폼의 경우 접미사 ‘add’를 일기 수정폼의 경우 접미사 ‘edit’을)를 props로 내려주어 기존 아이디 앞에 추가를 하니 문제가 해결되었습니다. ezgif-1-79bde03c29

  • 문제 해결 코드2
    ezgif-1-2d49cfcbb5
    • 하지만, 일기마다 각 수정 폼안의 버튼들의 id가 edit${key}로 동일했기 때문에 두번째 일기의 버튼을 눌러도 첫 번째 일기의 버튼이 동작하는 문제가 발생하였습니다. 따라서 일기Item의 id(PK)를 추가해주어 버튼들의 id가 겹치지 않게 할 수 있었습니다.
        // ./src/components/home/DiaryItem.tsx
           ...
           <DiaryFormContent onChange={onChange} inputs={inputs} suffix={`edit${item.id}`} />
           // item.id의 item은 props로 받아온 일기 하나의 정보이고, id는 일기 목록에서 일기를 구분할 수 있는 PK입니다.
         ```
      

3) 문제해결 완료

  • 모든 입력폼의 버튼들이 정상적으로 동작하는 것을 확인할 수 있고, html validator에서도 ‘Duplicate ID’ 에가 사라진 것을 확인할 수 있었습니다. ezgif-1-29aa0e174b



2. input의 checked 속성

1) 문제 상황

  • 일기 수정 폼에서 일기를 수정할 때, 제목과 내용만 변경하고 폼을 제출했을 때, 기분선택 버튼에 다음 옵션 중 하나를 선택하세요 라는 알림이 뜨는 것을 확인 할 수 있었습니다.
  • 수정 폼이기 때문에 이미 기분이 선택되어 있음에도 불구하고, 다음 옵션 중 하나를 선택하세요 라는 알림은 잘못 된 것이고 이 문제를 해결해야했습니다. ezgif-1-d7831b4ba1
  • 문제 코드

    // ./src/components/home/DiaryFormcontent.tsx
    ...
    {Object.entries(feelingData).map(([key, value]) => (
        <div key={value} className={styles['btn-feeling']}>
          <input
            name={`feeling`}
            id={`${suffix}${key}`}
            type="radio"
            className="a11y-hidden"
            value={key}
            onChange={onChange}
            required
          />
          <label htmlFor={`${suffix}${key}`} className={key === inputs.feeling ? styles.checked : ''}>
            <span>{value}</span>
          </label>
        </div>
      ))}

2) 문제 해결

  • defaultValue를 추가해주면 해결이 될까 싶어 속성 사용법에 대해 알기 위해 mdn을 검색해보니 빼먹은 속성이 있다는 것을 알게 되었습니다. mdn에서 input의 type이 ‘radio’일 때 사용법을 보니, checked 속성이 있다는 것을 알게 되었고 해당 속성을 사용하니 문제를 해결 할 수 있었습니다.
    image
  • 문제 해결 코드
    // ./src/components/home/DiaryFormcontent.tsx
    ...
    <input
      name={`feeling`}
      id={`${suffix}${key}`}
      type="radio"
      className="a11y-hidden"
      value={key}
      onChange={onChange}
      checked={inputs.feeling === key}
      required
    />
    • inputs의 feeling값이 key값과 같을 때 true를 반환함으로써 checked 속성을 true로 만들 수 있었습니다.

3) 문제 해결 완료

  • 제목과 내용만 변경하고 폼을 제출했을 때, 기분선택 버튼에 다음 옵션 중 하나를 선택하세요 라는 알림이 뜨지 않는 것을 확인 할 수 있습니다. ezgif-2-a298ab00ab



3. 기타 문제상황

1) 문제 상황

  • 초기 코딩시 module.css나 svg파일을 import 할 때 제대로 import되지 않고 에러가 뜨는 문제가 발생하였습니다.
  • Cannot find module '../../assets/logo.svg' or its corresponding type declarations.
    import { ReactComponent as ImageLogo } from '../../assets/logo.svg';
  • Cannot find module './Button.module.css' or its corresponding type declarations.
    import styles from './Button.module.css';

2) 문제 원인

  • Chat gpt에 물어본 결과, 원인을 알 수 있었습니다.
  • Chat gpt

    TypeScript와 CSS 모듈이 서로 다른 모듈 시스템을 사용합니다. TypeScript는 ES6 모듈 시스템을 사용하고, CSS 모듈은 컴포넌트의 스타일을 지역 스코프로 가져오는 것이 주요 목표입니다. 따라서 TypeScript는 CSS 모듈을 이해하지 못하고 해당 파일을 모듈로 가져오는 방법을 모릅니다. 이 문제를 해결하기 위해서는 타입 선언 파일을 만들어 TypeScript에게 CSS 모듈 파일에서 내보내는 클래스 및 스타일 정보에 대한 타입을 제공하면 TypeScript가 CSS 모듈 파일을 이해하고, 해당 모듈을 가져와서 사용할 때 타입 안전성을 유지할 수 있게 됩니다.

3) 문제 해결

  • Chat gpt가 알려준 대로 타입 선언 파일을 만들어 문제를 해결할 수 있었습니다
    // ./src/Global.d.ts
    declare module '*.module.css';
    declare module '*.scss' {
      const content: { [className: string]: string };
      export = content;
    }
    
    declare module '*.svg' {
      import React = require('react');
      export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
      const src: string;
      export default src;
    }

프로젝트하며 느낀점!

타입스크립트로 처음 해본 프로젝트였는데, 타입스크립트도 어렵지만 마크업도 어렵다고 느꼈다. 코딩은 어려운 게 많지만 그래도 그만큼 배울 수 있는게 많아서 재밌다는 것을 다시 한번 느끼게 된 프로젝트였다.
프로젝트 깃허브링크

profile
🙌꿈꾸는 프론트엔드 개발자 신은수입니당🙌

0개의 댓글