06) 주말은 왜이렇게 짧은지 왜냐면 이틀밖에 없으니까

이희주·2022년 5월 16일
0
post-thumbnail

오늘의 요약

오늘은 실무에서 사용되는 폴더 구조를 한 번 적용해 봤습니다

자바스크립트 부분과 HTML 부분, 쿼리 부분, 스타일 부분을 모두 잘게 쪼갰었죠?!
여기서 자바스크립트 부분을 담고 있는 컴포넌트를 container component 라고 불렀고,
HTML 부분을 담고 있는 컴포넌트를 presentational component, 줄여서 presenter 라고 부른다 했습니다.
이러한 방식을 줄여서 container/presenter 패턴이라고 부릅니다.

파일을 잘게 쪼개다보니, 연결하는 방법은 어렵지 않았죠? export와 import를 사용하여 연결해 주었습니다!
하지만, import를 한다고 내부에 있는 데이터까지 연결 되는 것은 아니였죠?, 두 컴포넌트간 데이터를 연결하려면, props를 사용해야 했습니다.
우리는 props를 사용함으로써 부모컴포넌트의 변수 또는 함수를 자식컴포넌트로 전달해 줄 수 있었습니다!
여기서 중요한 점은, 리액트의 데이터 흐름은 단방향이라는 것! 즉, 자식에서 부모로는 데이터를 전달할 수 없었단 점입니다!

마지막으로, 버튼의 색을 활성화 하기 위해 반드시 알아야 될 setState의 내부 동작 원리에 대해서 배웠습니다. setState를 한다고, 그 즉시 state가 변경되는 것이 아닌 한꺼번에 모아서 처리하는 것! 꼭 기억해주시길 바랍니다!

React

이번주 커리큘럼

오늘의 수업내용

1.실무적인 폴더구조(폴더 구조 나누기)
Container & Presenter
2.컴포넌트분리 및 데이터 전달
Props

지난시간 코드 리뷰 메인래퍼 안에 CardWrapper, BottomWrapper 있고 CardWrapper 안에 Header, Body가 있는 구조

FETCH_BOARD 가 백엔드에 요청을 하고 백엔드에서 DB로 가서 가지고 온 다음 {data} 에 할당 근데 비동기로 작동해서 데이터가 올 때까지 안기다리고 바로 보여주니까 데이터 안 뜰때 문구 보여줄 수 있게 옵셔널체이닝으로 ?. 넣어준다
비동기로 작동해서 먼저 보여줄 수 있는것 먼저 보여주고 데이터 들어오면 보여주기 (빠르게 보여주기 위해서)

boardId : router.query.[ ]
boardId의 마지막 부분은 boards의 폴더명과 동일하게

router 콘솔로 찍어보기

asPath가 실제 내 경로 : 주소 위치
pathname, route : 폴더상의 위치
=> 지금 이 주소에 있는 이 값이 aaa에 들어가는 것

router.query 클릭하면 aaa : "" 로 aaa라는 키에 밸류가 들어가있는 것을 확인 가능
그래서 router.query.aaa 하면 이 게시물의 id가 나오게 되는 것

boardId가 $boardId 에게 전달하고 그 밑에 $boardId에게 전달

게시글 아이디로 이동해줘!

등록할때는 비동기로 하면 안되는 이유?
result라는 곳에 게시물, 아이디 등을 받기 위해서는
기다렸다가 result에 값이 들어가서 _id를 받아와야 하기 때문에 동기로 작동하게 적용

push부분 이렇게 줄일 수 있음

게시물 작성하기 부분에서
writer === "" <- 비어있는 이부분

참과 거짓
거짓 => false, "" (문자열이 비어있는것), 0, undefined, null, Not a Number(NaN)
참 => true, " ", -1, 

writer가 비어있는게 맞으면 괄호 안의 값이 true로 바뀌고 if문이 실행되는 순서!

writer, password, title, contents 가 비어있지 않으면 true 로 바뀌게 되니까

writer && pasword && title && contents 로 쓸 수 있음

얘는 내용이 비어있다면 실행되는거니까 false값인 !contents 로 쓸 수 있음

optional-chaining

: 조건부 렌더링(화면에 그리기)을 도와주는 연산자

&&연산자를 삼항 연산자(?.)로 바꿔줬던 내용

&&연산자
data가 true면 data.fetchProfile을 보여주는것
data가 false 면 data를 보여주는것 (안보여주는거 아님)
근데 데이터가 없으면 undefined를 반환

// 조건 && 조건이 참일때 렌더 할 것
data && data.fetchProfile

||연산자
&&와 반대

// 조건 || 거짓이면 렌더 할 것
data || data.fetchProfile

data가 false면 뒤의 값을 보여주는 것
data가 true면 앞의 값을 보여주는 것

data?? data.fetchProfile

거짓 중에서 null과 비슷한 애들 (null, undefined)에 대해서만 뒤의 값을 보여주는 것 (거짓이면 다 보여주는건 data || data.fetchProfile)

옵셔널 체이닝 (optional-chaining)

//조건?.(data)가 있으면 렌더 할 것
data?.fetchProfile
💡 그럼 **optional chaining 이 데이터가 들어올 때 까지 기다려주는 건가요?**
*기다려 주는게 아닙니다!
데이터가 없을때는 undefined를 리턴했다가 데이터가 들어오면 들어온 데이터를 가지고 화면을 다시 렌더해주는 것 입니다. 이를 재렌더링이라고 부릅니다.*

💡 **optional chaining 언제 사용하나요?**
이름에서 알 수 있는것 처럼, **데이터를** **화면에 렌더링 할 때 사용**합니다. 
백엔드와 통신해서 받아오는 데이터들은 시간이 걸리기 때문에 옵셔널 체이닝을 사용해야 화면에 오류가 안나고 잘 렌더 됩니다.

class/pages 주소 설계

게시글등록 페이지 /boards/new	
게시글상세 페이지 /boards
게시글목록 페이지 /boards/aksjdlaksjdfalw-182832

상품등록 페이지 /products/new
상품상세 페이지 /products/wefjlaksdf-1412123
상품목록 페이지 /products

이렇게 하면 페이지들을 다 같은 폴더로 묶을 수 있음

삭제페이지는 없는거고,

게시글수정 페이지의 경우 게시글 등록처럼이 아닌
상세페이지 게시물을 수정해줘 ! 라고 해야 하기 때문에

/boards/edit 이 아닌 
/boards/상세페이지아이디/edit 

상품도 똑같이

/products/wefjlaksdf-1412123/edit

Container & Presenter

폴더 구조 체계화

실무용 폴더구조 (container / presenter)
실무에서 사용하는 폴더 구조의 여러가지 방법을 패턴 이라고 부른다

페이지 컴포넌트 안에 그냥 컴포넌트들

이런 컴포넌트들을 조립해서 하나의 페이지를 만들고,
바깥에 있는게 페이지 컴포넌트

이런 컴포넌트들의 폴더를 어떻게 나눠야 할까??

  1. javascript(기능)와 html(화면) 영역으로 나누기

container는 기능
presenter는 보여주는애

기능과 화면으로 나눈 하나의 파일을 두개의 파일로 쪼갠다

BoardWrite-container , BoardWriteContainer 등등
(한 페이지의 코드를 70~100줄정도로 줄인다!)

둘다 함수형 컴포넌트 => 둘다 자바스크립트 영역과 html영역이 있는 것
근데 하나는 기능만 담당하고 하나는 화면만 담당한다

!!!!
중요중요
컴포넌트가 두개지만
이걸 실제로 실행할 때는 두개의 컴포넌트가 하나로 합쳐진다

컴포넌트 간에는 부모와 자식이 존재하는데

presenter가 container로 import 되어서 실행되기 때문에
presenter가 자식, container가 부모
자식이 부모 위치로 들어가서 합쳐져서 1개의 소스코드로 실행 됨

??
어차피 실행될떄 합쳐져서 실행되는데 나눈 이유?
한 파일의 소스코드를 짧게 쓰기 위해서(유지보수가 용이하게)

근데 파일이 나눠지고 나니까
onChange handleChangeWriter가 어디서 나와서 실행되는건지 모르겠네???? => props 사용

부모컴포넌트에서 자식컴포넌트로 물려주는 변수,함수,데이터 props

Props

부모 컴포넌트가 가지고 있는 변수, 함수, 데이터들을 자식 컴포넌트 에게 물려주는 것
(자식이 부모에게 넘겨주는것은 안됨! 그래서 리액트에서의 데이터 흐름은? 단방향 구조)
props를 물려줄때는 객체로 묶어서 넘어감

1. aaa={handleChangeWriter} 입력
이게 props={aaa:handleChangeWriter} 라는 객체로 변함
aaa라는 키에 handleChangeWriter 밸류가 들어옴

2.presenter안의 (props)로 전달
props.aaa 하면 handleChangeWriter 나옴

  1. onChange={props.aaa}가
    실제로 실행될때는 handleChangeWriter가 됨!

aaa는 객체의 키일 쁀 그래서 aaa가 변경되면 props.aaa도 같이 변경
그래서 보통 밸류값과 같은 키값으로 사용
handleChangeWriter={handleChangeWriter}

//props 내려주기
//부모 컴포넌트 _ container 부분
const BoardWrite = ()=>{
		const [writer, setWriter ] = useState()
		const handlechangeWriter = (e)=>{
					writer = e.target.value
					setWriter(writer)
						}
	return(
		// 자식 컴포넌트 _ presenter 컴포넌트 
		// 본격적으로 props를 내려주는 부분입니다.
		<BoardWriteUI propsName={handlechangeWriter}/>
	)
}
//props받아오기
//자식컴포넌트 _ presenter 부분

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

폴더 구조 체계화 실습

여러 컴포넌트, 여러페이지에서 사용되는 함수같은것들을 구조별로 나눠 체계화 하기

둘다 컴포넌트인데

src/commons 두번이상 쓰이는 컴포넌트들
src/components/commons 
src/components/units 한번만 쓰이는 컴포넌트들 로 나눔

각각의 컴포넌트를 pages의 index에 합쳐주기

여기서 count 는 각각의 state
만약 qqq에서 zzz의 count2를 쓰고싶다면 props

presenter, container, index 세개가 합쳐져서 pages/index 파일에 접속했을때 볼 수 있는 것

이 페이지들이
06-01-container-preseneter의 index 로 보내진것

06-01-container-presenter/index.js : 페이지 컴포넌트
container.js : 기능
presenter.js : 화면
queries.js : 쿼리.네트워크
styles.js : css

Daily-scrum

MDN 보는 방법, 배열의 내장함수(기본)

MDN : HTML, CSS, JS 사전

MDN사용 가이드 라인

  1. 내가 궁금한 메서드 검색
  1. 시도해보기 부분을 보며 사용 방법 익히기
  1. (중요!!)구문 부분의 매개변수, 반환값 부분을 보며 디테일한 사용 방법 익히기

실무 전용 반복문 알아보기 !
: map, forEach, filter

함수의 괄호!!

→ 함수의 괄호는 가끔 생략되는데 언제 생략이 가능하냐면?

  1. 함수의 바디의 종류 {중괄호},(소괄호)
    • { 중괄호 } : return 을 적어야 return 이 일어남
    • ( 소괄호 ) : return 을 적지 않아도 암묵적으로 return이 일어남
  1. 바디의 괄호 생략
    → 바디의 괄호 생략은 코드가 한줄일때만 가능하며, 생략시 코드가 암묵적으로 리턴됨
  1. 매개변수의 괄호(소괄호) 생략 : 매개변수가 한개인 경우 생략 가능
    (이부분)⇒{}

함수의 바디가 한 줄일 경우에는 리턴을 암묵적으로 포함하며 괄호를 생략 할 수 있음

map

배열을 변형하는 메서드
: 배열의 모든 원소에 대해 함수를 호출한 결과를 모아 새로운 배열을 반환 (실무에서는 반복문으로 자주 사용됨)

사용방법

arr.map((arr_item)=>{
	//모든 배열의 원소에게 반복실행할 코드
})

map의 예제

let num = [1,2,3,4,5]
let newNum = num.map(num_item => num_item*3)

결과<
newNum = [3,6,9,12,15]

예제2

let child = ["은정","재준","시윤","주은"]
let newChild = child.map(i => i +" 어린이 ")
child.map((aaa)=>{return `${aaa} 어린이`})
console.log(newChild)
실행 결과 [ '은정 어린이 ', '재준 어린이 ', '시윤 어린이 ', '주은 어린이 ' ]

forEach 와 map의 차이점 : 반환값
forEach는 반환값이 없다

for은 map, forEach보다 속도는 느리지만 효율성은 좋을 수 있따

Algorithm class

데이터의 타입을 확인하고 싶다면

function solution(s)
	console.log(s, typeof s)

문자열을 숫자로 변환하는 기능

function solution(s)
	console.log(Number(s), typeof s)

substring() 문자열을 잘라주는 메서드

str = "123456"
str.substring(1,5)
결과값 "2345"

slice() 잘라주는 메서드

arr = [1,2,3,4,5]
arr.slice(1,4)
결과값 [2,3,4]

알고리즘 문제 중 어려웠던 것 : 같은 문제는 싫어!

// 문제 설명
배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다. 
이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다. 
단, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 합니다. 예를 들면,
arr = [1, 1, 3, 3, 0, 1, 1] 이면 [1, 3, 0, 1] 을 return 합니다.
arr = [4, 4, 4, 3, 3] 이면 [4, 3] 을 return 합니다.
배열 arr에서 연속적으로 나타나는 숫자는 제거하고 남은 수들을 return 하는 solution 함수를 완성해 주세요.
// 제한사항
// 배열 arr의 크기 : 1,000,000 이하의 자연수
// 배열 arr의 원소의 크기 : 0보다 크거나 같고 9보다 작거나 같은 정수

푸는 방법

function solution(arr) {
  var answer = []
 
  //1.arr배열의 각각의 숫자 (원소)를 가져오기 위한 반복문
  for (let i =0; i<arr.length; i++) {
    // 2.지금의 숫자와 그 뒤에 있는 숫자가 서로 동일한지를 체크하는 조건문
    if( arr[i] !== arr[i+1]) {
      answer.push(arr[i])
    }
  } 
  return answer
}

solution([1,1,3,3,0,1,1])

배열 arr의 크기는 length로 가져올 수 있음
배열의 0번째 인덱스부터 배열의 마지막 인덱스까지 각각 하나씩 가져옴

그러기 위해서는 포문을 이용해서 어레이의 각각의 인덱스 값을 가져옴
i값의 인덱스의 최초값부터 가져올꺼니까 i = 0 부터 시작
length가 10이라면 인덱스는 9까지 가져와야하니까 i < arr.length

for문으로 i를 콘솔로그 찍어봄 arr의 각 인덱스 값을 가지고 오고 있음

a의 첫번째 인덱스를 가지고오고, 그 다음인덱스를 하나 가지고옴
두번째 인덱스를 가지고오고 세번째인덱스를 하나 가지고옴
하나씩 비교해서 지금의 숫자와 같지 않으면 앤서에 푸시해서 넣어줌

TIL

  1. 자유게시판 만드는 과제 프리보드 밑에 목록으로,수정하기,삭제하기 버튼 넣어야되니까 래퍼 하나 밖으로 빼고 밑에 푸터래퍼 만들어주면 좋을 것 같다

  2. 노션 프로그래머스 같은 숫자는 싫어 다시 풀고 메서드 들 공부하기

  3. mdn 많이 찾아보고 사용방법 익힐 수 있게 노력하기

  4. emotion 가상선택자 사용방법

export const SubmitButton = styled.button`
    width: 179px;
    height: 52px;
    background-color: #ffd600;
    border: 0;
    &:disabled {
        background-color: gray;
    }
    cursor: pointer;
`

오늘 과제 중 버튼을 disabled 상태로 두고 버튼에 input값이 들어오면 버튼 색상을 변경해주는 게 있었는데, emotion에서 가상선택자를 사용하는 방법을 몰라서 동기들과 열심히 찾아보다가 알게되었따!!! &:어쩌구 이렇게 쓰면 된다는 것,, !!!

그리고 disabled 상태인 버튼에 작성자, 비밀번호, 제목, 내용이 입력되면 버튼이 활성화 되도록 하기 위해서 어떻게 해야할지도 엄청 고민했는데! 생각보다 엄청 엄청 간단한거였다..!
disabled 가 true인 상태에서 내용이 입력되면 disabled가 false가 되게 하기 위해서 이렇게 써준다!
const keyUp = !(writer && password && title && contents)

profile
어제보다 오늘 발전하는 프론트엔드 개발자

0개의 댓글