프론트엔드 - 8

송현섭 ·2023년 3월 23일

프론트엔드

목록 보기
9/24
post-thumbnail

공통적으로 쓰이는 함수를 한 곳에 저장하여 사용하기


  • 같은 함수를 여러 번 만들어서 쓰는 것이 아닌, 한 번 만들어놓고 필요할 때마다 import로 가져오는 방식

  • 이런 방식은 혹시나 회사의 디자인 수정이나 클라이언트 요청으로 기존의 사용방식, 패턴을 수정해야 할 때 각 페이지 하나하나 바꿀 필요 없이 함수의 코드만 수정하면 해당 함수가 적용된 모든 페이지의 설정이 바뀜 (유지, 보수면에서 유리)





ex. 각 페이지의 날짜표기를 위해 만든 getDate 라는 이름의 함수

freeboard_frontend / src / commons / libraries / utils.js


export const getDate = (date) => {
	const _date = new Date(date)
	const yyyy = _date.getFullYear()
	const mm = _date.getMonth() + 1 ; // 여기서 +1을 하는 이유는 월을 0~11로 받아오기 때문입니다
	const dd = _date.getDate()
	return `${yyyy}-${mm}-${dd}`
}
  • 위의 함수의 매개변수 date에 인자로 들어가면 각각의 년도, 월, 일을 계산하여 반환해 줌





import { getDate } from '~~/src/commons/libraries/utils';
export default function BoardListUI() {

	...

	return (
	<div>
	...
	{props.data?.fetchBoards.map((el, index) => (
		...
		<div>
			{getDate(el.createdAt)}
		</div>
	))}
	</div>
	)
}
  • 이 함수를 이용해 위와 같이 import 하여 필요할 때마다 불러와서 사용가능

  • 혹여나 표기방식의 변경(ex.날짜 표기시 '-'를 생략한다던지)이 필요해도 해당 함수의 내용만 수정하면 함수가 적용된 모든 페이지가 한 번에 바뀜









컴포넌트 재사용성


  • 하나의 페이지를 각각 컴포넌트로 나누어주는 이유는 재사용성과 유지보수가 용이하기 때문

  • 비슷한 레이아웃을 가진 컴포넌트의 경우 일부 데이터만 변경하는 식으로 하나의 컴포넌트를 공통으로 사용하는 방식이 효율적임




컴포넌트 재사용 예시

  1. BoardNew, BoardEdit 두 페이지에서 같은 컴포넌트를 공유한다고 가정했을 때, 각 페이지의 index.js 를 만들고 공통으로 쓸 컴포넌트를 src 폴더 안에 만듬
// src/components/units/board/09-board-component/index.js
export default function BoardComponent() {
  return (
    <div> {/* 공통 컴포넌트에서는 사용하는 곳에 지정된 css의 영향을 방지하기 위해 div 태그를 사용해줍니다. */}
      <h1>등록페이지</h1>
      제목: <input type="text" />
      내용: <input type="text" />
      <button>등록하기</button>
    </div>
  );
}







2. 나눠 진 각 페이지에 한 쪽은 false, 다른 한 쪽은 true 값을 하위 컴포넌트로 상속해 줌

  • BoardNew 페이지
import BoardComponent from "../../../src/components/units/board/09-board-component";

export default function BoardComponentNewPage() {
  return <BoardComponent isEdit={false} />;
}



  • BoardEdit 페이지
import BoardComponent from "../../../src/components/units/board/09-board-component";

export default function BoardComponentEditPage() {
  return <BoardComponent isEdit={true} />;
}








  1. 공통으로 사용하는 컴포넌트 중 presenter 컴포넌트에서 props로 boolean 값을 받아오고 이를 삼항연산자로 활용
export default function BoardComponent(props) {
  return (
    <div>
      <h1>{props.isEdit ? "수정" : "등록"}페이지</h1>
      제목: <input type="text" />
      내용: <input type="text" />
      <button>{props.isEdit ? "수정" : "등록"}하기</button>
    </div>
  );
}
  • 받아온 boolean값(props.isEdit) 에 따라 삼항연산자로 어떤 것이 표시될 것인지를 결정

  • 이를 통해 하나의 컴포넌트에서 두 개의 페이지에 따라 따로따로 활용이 가능









수정 페이지의 문제점 2가지


* 만든 수정 페이지

-게시글 페이지에서 [수정하러가기] 버튼을 누르면 router로 수정페이지(등록페이지와 공유되는 컴포넌트)로 이동

-수정 항목 입력 후 [수정하기] 버튼을 누르면 updateProduct [gql] 로 정보 업데이트 API 요청이 가고 DB의 정보가 입력한 정보로 바뀜





- 문제점 1 => 수정 페이지로 이동하면 입력하는 input 창이 빈 칸으로 되어 있음 (게시글 등록 페이지의 초기화면과 똑같음)




[해결방안]

  1. 수정 페이지(pages/[number]/edit) 안에 경로를 통해 가져올 수 있는 router를 이용해서 게시글의 query를 조회하고 이를 통해 게시글 번호를 획득(router.query.number)







2. 획득한 게시글 번호를 이용해 fetch 로 DB에서 받은 각 정보를 {data}에 담고 이를 props로 하위 컴포넌트(Container)에 상속




  1. 상속받은 데이터는 다시 하위 컴포넌트(Presenter)로 상속되어 이동 [prop drilling]
  1. Presenter 에서 각각의 input에 defaultValue 설정
    *defaultValue = input 태그의 속성 중 하나로 input 안에 들어가는 default 값


[결과적으로 상속받은 data 내에 각 정보들(ex. props.data.fetchBoard.writer)을 defaultValue의 값으로 두면 앞으로 수정페이지를 들어갈 때마다 작성한 글의 데이터가 기본값으로 input 창에 표시됨]











- 문제점 2 => 세 개의 input 창(A,B,C) 중 A input 창에만 값을 입력하고 수정 후 게시글을 다시 불러오면 입력 안 한 B 와 C 는 "" 으로 변경되어 있음
(원래는 변경한 데이터 외에 다른 입력 데이터는 그대로 보존되어야 정상)




[해결방안]

  • 위 문제가 발생하는 이유 => defaultValue 는 input의 속성
    *육안으로는 값이 보이지만 default 값일 뿐 실제로 input 내에 입력된 건 아무것도 없음 (DB로 전송 시 default 값 그대로인 부분은 공백과 같은 취급)




해결 => input 입력 값 중 값이 변경되는 것들만 variables 객체에 할당

const onClickUpdate = async () => {
    const myVariables = {
      number: Number(router.query.number),
    };
    if (writer) myVariables.writer = writer;
    if (title) myVariables.title = title;
    if (contents) myVariables.contents = contents;

    const result = await updateBoard({
      variables: myVariables,
    });
  };
  • onClickUpdate = [수정] 버튼
  • writer, title, contents = input의 입력되는 값 (useState로 할당한 변수)


  1. myVariables 라는 빈 객체 생성 (API 요청에 필수정보인 number의 key와 값은 기본으로 입력) *버튼 누를 때마다 변경 사항이 DB로 전송되어야 업데이트가 된 거니까

  2. if문으로 writer, title, contents 각 input값이 존재한다면 (공백"" 이 아니라 수정페이지에서 값이 입력된다면) myVariables 객체에 해당 key와 값(value)을 입력


  1. Gql 내의 변수 variables 에 만들었던 myVariables 객체를 값으로 할당




[결과적으로 수정되는(수정페이지에서 입력되는) 값들만 variables 객체 안의 값으로 들어가게 되고 이 값이 API 요청되어 DB로 전송됨]

profile
막 발걸음을 뗀 신입

0개의 댓글