[코드캠프]6일차_TIL

윤성해·2023년 3월 20일
0

프론트엔드_TIL

목록 보기
6/27
post-thumbnail

🏷️ 수업목차

  1. 폴더구조
  2. props
  3. export vs export default
  4. atomic 패턴

1. 폴더구조

주소 설계할 때 아래의 이미지처럼 만들 수 있습니다.

그렇다면 수정하기는 /boards/edit?

  • 수정하기는 몇번째 게시글을 수정할 것인지 설정할거라서 보통

    폴더명이 위와같은 규칙을 따른다 => 레스트풀 하다! 라는 이야기와 유사하게 생겼습니다.

실무용 폴더구조를 만들 때, 여러패턴(방법)들이 있지만 리액트에서 사용하는 유명한 패턴으로는 container / presentational 패턴, hooks 패턴, atomic 패턴이 있습니다.
1. container / presentational (클래스형)
2. 훅스패턴= (useState..등 유즈 로 시작하는애들 기반으로 폴더 만들자) -> 함수형형식
3. 아토믹 패턴 (부품을 조금 더 체계화해보자)

1) container / presentational 패턴

container / presentational 패턴이란, 소스코드를 자바스크립트(기능)와 JSX (UI)로 나누는 방법을 의미합니다.

  • container는 자바스크립트(기능) 부분을 의미
  • presentational은 JSX(UI) 부분을 의미


위 파일을 2개의 파일로 나누는 방법은 아래와 같습니다.

파일을 나눴어도 실행될 때는 하나로 합쳐져서 실행 되어야 합니다.
하나로 합쳐서 실행하는 방법은 부모컴포넌트에 자식컴포넌트를 불러오는 것 입니다.

위와 같이 자식컴포넌트인 presenter를 부모 컴포넌트인 container에 불러와 하나로 합쳐 실행 하는 것 입니다.
반드시 기억해야하는 점은, 파일은 두개로 나뉘어져 있지만 실행시에는 pages에서 하나로 합쳐져서 실행된다는 점 입니다.
우리가 브라우저로 볼 수 있는 컴포넌트는 pages에 있는 index.js 뿐이기 때문에 하나로 합쳐둔 container를 pages에 가지고 와서 import 해주셔야 합니다.

💡 부모 컴포넌트와 자식 컴포넌트
import되어 불려가는 컴포넌트를 자식 컴포넌트라고 합니다.
반면 import하여 불러오는 컴포넌트를 부모 컴포넌트라고 합니다. 자식컴포넌트는 부모 컴포넌트 안에 포함되는 구조 입니다.

추가 참고 내용

  • 모든 페이지는 App컴포넌트에서 합쳐진다.

  • 왼쪽 부모컴포넌트 , 오른쪽 자식 컴포넌트!
    오른쪽 프리젠테더가 왼쪽 컨테이너로 불려와서 리턴 되고 연두색 박스처럼 다 하나로 보이게된다.

  • 부모컴포넌트가 가지고있는 기능들을 자식컴포넌트에게 물려주는 변수또는 함수이다. 자식이 부모에게 줄 수는 없음. (리액터 데이터 흐름 : 단방향 관계)
    어떻게? -> props 를 통해서!객체가 만들어진다고 보면 된다.

💡실습 코드 캡쳐

  • 최종적으로 , 자식이 부모에게 임포트 되고 초ㅣ종적으로 앱에서 보이게 된다(연두색 박스)

2. props

컴포넌트를 2개로 나누면서 데이터와 기능의 연결고리가 끊어지게 됩니다.
이를 props가 연결해주게 되며, props란 부모 컴포넌트가 자식 컴포넌트에게 물려주는 변수/함수 를 의미합니다.
부모 컴포넌트가 props를 물려줄때는 객체로 묶어서 넘기게 됩니다.

1) props를 주기 _ 부모 컴포넌트

자식 컴포넌트 태그의 propsName 잘 보기

//부모 컴포넌트 _ container 부분

const BoardWrite = ()=>{
		const [writer, setWriter ] = useState()
		const handlechangeWriter = (e)=>{
					writer = e.target.value
					setWriter(writer)
						}

	return(
		// 자식 컴포넌트 _ presenter 컴포넌트 
		// 본격적으로 props를 내려주는 부분입니다.
		<BoardWriteUI propsName={handlechangeWriter}/>
	)
}

위와 같이 props를 넘기게 되면, props = { propsName : handlechangeWriter } 형태의 객체로 넘어가게 됩니다. 또한 props는 여러개를 내려 줄 수 있습니다.

2) props 받아오기

//자식컴포넌트 _ presenter 부분

//파라미터 부분에 props를 적어주셔야 받아 올 수 있습니다.
const BoardWriteUI = (props)=>{
		return(
			<Wrapper>
				<Writer
					type = "text"
					placeholder = "작성자를 적어주세요"
					// 본격적으로 props를 내려받는 부분입니다.
					onChange = {props.propsName}
					/>
			</Wrapper>
		)
}

파라미터 부분에 props를 적지 않으면 받아 올 수 없으니 주의 해주셔야 합니다.
또한 객체로 넘어오기 때문에 받아온 props를 사용하려면 객체의 속성을 꺼내오는 것 처럼 사용해주셔야 합니다. 따라서 props.propsName 형태로 사용해야 합니다.

  • 리액트는 부모가 자식에게 props만 줄 수 있으며 자식이 부모에게 주는 것은 안됩니다. 이것을 데이터흐름이 단방향 구조 라고 합니다.

3) export vs export default


위 이미지처럼, import 해올 때 어떤것은 중괄호를 사용했고, 어떤것을 중괄호가 없었습니다.
중괄호의 사용 여부는 export를 하냐, export default를 사용하느냐에 따라 결정됩니다.

  • **export** : 한 컴포넌트 내에서 여러개를 내보내기 때문에 중괄호를 사용해 필요한 것들만 import합니다. import할 때는 export한 이름 그대로 불러와야합니다.

  • **export default** : 한 컴포넌트에서 한개만 내보내기 때문에 중괄호를 사용하지 않고 import 하게 됩니다. import 해올 때 export한 이름이 아니어도 괜찮습니다.
    한 컴포넌트에서 한개만 emport했기 때문에 파일의 경로만 제대로 지정되면 됩니다.

  • export를 한번에 묶고싶을 때는 import * as S from "경로"를 사용합니다.

    아래 이미지처럼 css를 작성해주었습니다!

💡 정리해보면, 이렇게 폴더를 쪼개놓으면 코드의 유지보수와 가독성에 유리합니다. 에러가 나도 어디서 에러가 난건지에 따라 해당 파일에 들어가서 바로 고쳐주면 해결이 쉽습니다!
css 문제 -> styles 파일
html 문제 -> 프리젠터 파일
자바스크립트 문제 -> 컨테이너 파일
페이지접속 문제 -> 페이지 파일
전체적인 이상함 > 앱 파일


🤷🏻‍♀️ 궁금한 것

  • Atomic 패턴의 장점과 단점은 공부해보기
  • export를 한번에 묶고싶을때는 import * as S from "경로"를 사용하면 이전에 하나씩 적어주던 것보다 편리하다고 하셨는데, 그래도 이미지 처럼 S.RedInput 이렇게 하나씩 적어주어야 하는거면 똑같지 않나?????? 똑같이 하나씩 써줘야하는 것 같아서 뭐가 다른건가 궁금하다.

    위 이미지는 기존에 임포트 해주던 것

    위 이미지는 오늘 한번에 묶는 것을 배운 것!

❗️알게된 것

  • 수업을 들으며 실습을 할 때, style 파일의 부모속성이 presenter 파일이었는데, css 속성을 presenter의 부모인 container 에 작성을 하셨다. 부모가 자식에게 속성을 물려줄 수 있다고 했는데 내가 이해하기로는 부모의 부모에게 작성을 해주어서 질문을 했다! ➡️ 이경우는 모든 컴포넌트가 같은거고 쪼개져있는 것 뿐이라서 어떤 파일에 작성해주던 상관이 없다는 답을 받았다!

✨ 느낀점

오늘 과제는, 리액트 파일을 html, css, 자바스크립트 등 컴포넌트 단위로 쪼개주는 것이었다. 쉬울 줄 알았는데 에러의 연속이라 정신 나갈뻔 했지만ㅎㅎ 페어분들이 도와주셔서..진짜 이상한 에러도 한시간 반만에(?)🙄 잡았다고..한다 물론 내가 말고 페어분께서 :).....(괜쟈나 할 수 있어!!)

그래서 내가 만난 에러들과 실수들을 대충 정리해보자면

  1. 경로 설정 완전 이상하게 했음. 같은 파일안에 있는애는 ../../../../ 요따구 아니고 ./ 해주면 바로 나옵니다.
    -> 근데 도대체 위처럼 ../ ../ ../의 연속이었는데도 자동으로 나왔지..?(암튼 얘때문에 에러였음)
  2. 괄호 안에 props 안썼음. -> 받아주는 자식페이지에서 꼭 써주기!
  3. css import를 page 폴더에 (부모폴더 아님) 해줌
  4. 다른 폴더에서 변수명 [qqq] 있으면 다른 변수명으로 바꿔주기
  5. 오타오타오타오타오타오타오타오타오타!!!!!!!!!!!!!!!!!!!!!!!!
  6. html 부분에 객체로 만들어서 넣어주기. { props.writer } 이런 형태!

근데 도저히 모르겠는데 에러메세지가 있었다. 자꾸 인트값 어쩌고 하는데 분명 잘 썼거든유.. 이거 수정 안해주었는데도 할튼 잘 마무리 하긴 했다.
혹시 몰라 적어놔야지(두개임)

1.

{"errors":[{"message":"Variable "$createProductInput" got invalid value "" at "createProductInput.price"; Int cannot represent non-integer value: ""","locations":[{"line":1,"column":41}],"extensions":{"code":"BAD_USER_INPUT","exception":{"stacktrace":["GraphQLError: Variable "$createProductInput" got invalid value "" at "createProductInput.price"; Int cannot represent non-integer value: ""","    at /newbizcode_backend_common/node_modules/graphql/execution/values.js:116:15","    at coerceInputValueImpl (/newbizcode_backend_common/node_modules/graphql/utilities/coerceInputValue.js:132:9)","    at coerceInputValueImpl (/newbizcode_backend_common/node_modules/graphql/utilities/coerceInputValue.js:106:34)","    at coerceInputValueImpl (/newbizcode_backend_common/node_modules/graphql/utilities/coerceInputValue.js:56:14)","    at coerceInputValue (/newbizcode_backend_common/node_modules/graphql/utilities/coerceInputValue.js:39:10)","    at _loop (/newbizcode_backend_common/node_modules/graphql/execution/values.js:109:69)","    at coerceVariableValues (/newbizcode_backend_common/node_modules/graphql/execution/values.js:121:16)","    at getVariableValues (/newbizcode_backend_common/node_modules/graphql/execution/values.js:50:19)","    at buildExecutionContext (/newbizcode_backend_common/node_modules/graphql/execution/execute.js:205:61)","    at executeImpl (/newbizcode_backend_common/node_modules/graphql/execution/execute.js:103:20)"]}}}]}

2.

<!DOCTYPE html><html><head><style data-next-hide-fouc="true">body{display:none}</style><noscript data-next-hide-fouc="true"><style>body{display:block}</style></noscript><meta name="viewport" content="width=device-width"/><meta charSet="utf-8"/><title>Application error: a client-side exception has occurred</title><meta name="next-head-count" content="3"/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills.js?ts=1679311184807"></script><script src="/_next/static/chunks/webpack.js?ts=1679311184807" defer=""></script><script src="/_next/static/chunks/main.js?ts=1679311184807" defer=""></script><script src="/_next/static/chunks/pages/_app.js?ts=1679311184807" defer=""></script><script src="/_next/static/chunks/pages/_error.js?ts=1679311184807" defer=""></script><script src="/_next/static/development/_buildManifest.js?ts=1679311184807" defer=""></script><script src="/_next/static/development/_ssgManifest.js?ts=1679311184807" defer=""></script>
profile
Slow and steady wins the race.

0개의 댓글