본캠프 첫주가 지났다. 어찌어찌 한 내가 참 대다내!
이번주랑 다음주가 엄청 중요하다고 하니까 열심히 해보쟈고~~
아직은 이해보다는 감으로 하는중..!😊
- REACT
- HTTP 통신
- API
- 동기, 비동기통신
- apollo-client 로 graphql 뮤테이션 실행
- 라우팅
React는 javascript를 쉽고, 효율적으로 사용할 수 있도록 Facebook에서 만든 도구
입니다.
리액트는 부품 조립방식으로 개발이 진행되며, 핵심은 컴포넌트 기반
입니다!
기존에 페이지를 각각 만들었다면 리액트는 부품을 만들어서 조립하는 방법이라서, 큰 서비스를 만들때 유리합니다.
💡컴포넌트란? UI 또는 기능을 부품화 해서 재사용 가능하게 하는 것
대표적인 서비스로는 페이스북, 인스타그램, 에어비앤비
등이 있습니다.
react에서 다른 폴더에 있는 파일을 불러올 수 있는데, 실무에서는 html
, css
, javascript
파일을 각 각 따로 만들어서 필요에 따라 불러옵니다.
- import - 외부에서 가져오기
- export - 외부로 내보내기
JSX는 React에서 사용하는 React 전용 HTML
입니다.
React에서는 HTML 대신 JSX(React 전용 HTML)를 사용합니다.
속성값의 대소문자 정도 차이 등을 제외하곤 거의 비슷합니다.
CSS-IN-JS
는 CSS를 JS상수에 저장해서 사용하는 방법
입니다.
오른쪽은 동일한 CSS를 Title이란 상수에 저장한 것입니다.
이렇게 저장한 상수는 마치 HTML 태그처럼 사용
할 수 있습니다.
자바, 파이썬은 브라우저로 보이는것이 아닌 게임이나 엑셀을 개발할 때 쓰이는 언어입니다.
이러한 언어를 쓰던 사람들이 홈페이지를 만들어보고자 자바스크립트를 접해보다가 런타임이 웹브라우저에서만 한정되던 자바스크립트를 자바, 파이썬 처럼 클릭해서 실행할 수 있는 프로그램 처럼 만든것이 node.js 입니다. 즉 node.js는 언어가 아니고 내 컴퓨터에서 직접 실행하는 실행 프로그램
입니다.
컴포넌트는 아래의 이미지처럼 동일한 UI를 재활용
하고, 안에 데이터와 이미지만 바꿔
줍니다.
원본만 변경하면 모두 변경되는 컴포넌트(import로 가져오기)에 비해
복사/붙여넣기
로 코드를 작성하고 모든 UI를 노란색으로 변경하려면, 코드를 하나하나 수정해주어야 합니다.
리액트에서 컴포넌트 작성 방법은 2가지가 있습니다.
함수형이 훨씬 간단해보이고, 함수형은 화살표 함수
로도 적용이 가능합니다.
함수형이 가독성도 좋고 훨신 간단해보이지만 아직 클래스형으로 작성된 코드들이나 프로젝트들이 많으므로 둘다 알고있어야함
클래스에서 사용하던 기능들을 함수형에서는 모두 흉내낼 수 없습니다. 그래서 함수형 컴포넌트에서도 클래스형 컴포넌트와 동일한 기능을 사용 가능하도록 도구를 만들어 주었습니다. 이 도구를 Hooks(훅) 이라고 부릅니다.
대표적인 훅에는 useState, useEffect가 있는데, 보통 use
어쩌구 하면서 시작됩니다!
state란 리액트 컴포넌트에서 데이터를 담기 위한 상자
입니다.
자바스크립트에서 데이터를 담기 위한 상자로 변수
를 사용했습니다.
다시 말해, state는 컴포넌트에서 사용하는 변수
입니다.
state
: 컴포넌트에서 사용하는 변수(state)
setState
: 컴포넌트에서 사용하는 변수(state)를 바꿔주는 기능
useState
: 컴포넌트에서 사용하는 변수(state)를 만들어주는 기능
// 자바스크립트에서 변수 만들기 변수만드는기능 변수명 = 담을내용 ==> let classmate = "철수" // 리액트 컴포넌트에서 변수 만들기 const [변수명] = 변수만드는기능(담을내용) ==> const [classmate] = useState("철수")
// 자바스크립트에서 변수 바꾸기 let classmate = "철수" classmate = "영희" // classmate 가 영희로 바뀝니다. // 리액트 컴포넌트에서 변수 바꾸기 const [변수명, 변수바꾸는기능] = 변수만드는기능(담을내용) const [classmate, setClassmate] = useState("철수") setClassmate("영희") // classmate 가 영희로 바뀝니다.
- 여기서 const(변수)는 let 해도됨 아무거나 쓴거임
- (0)은 카운트에 넣어준 초기값을 의미함
[]
(대괄호)는 그냥 외우기 공식이라 생각하기 => 원리는 일단 나중에- setCount -> 변수 바꿔주는 함수
- useState -> 컴포넌트 만들어주는 (변수 만들어주는 함수)
❗️let은 리액트 전용 html에서 변경을 감지하지 못하기때문에 state 써야함!
HTTP
란 두 컴퓨터간에 텍스트 데이터를 주고 받는 길
입니다.
HTTP 라는 길로 요청(request)과 응답(response) 2가지를 서로 주고 받을 수 있습니다.
웹브라우저에서 홈페이지(Front-end)가 실행중이라면, 작성한 게시물 텍스트 데이터를 HTTP를 통해 Back-end 컴퓨터로 보내고 Back-end 컴퓨터에게 이 데이터를 데이터베이스에 저장 해달라고 요청합니다.
요청을 받은 Back-end 컴퓨터가 성공, 실패 등 처리 결과를 응답합니다.
통신요청 / 응답
헤더와 바디가 존재하며 요청, 응답도 같은 포맷임
헤더는 내용을 요약해줍니다.
요청의 텍스트 안에는 객체가 들어가있습니다.
요청/응답의 보내는이가 바뀌어있는것을 확인할 수 있습니다.
응답을 할 때는 상태코드가 붙습니다.(성공인지, 에러인지, 어떤오류인지...)
API는 백엔드 분들이 만든 함수(기능)이고, 버튼 기능마다 api가 따라다녀야 한다.
ex) 게시물 저장 API, 프로필 저장 API, 프로필 조회 API...
API의 종류는 크게 rest-API
, graphql-API
로 2가지가 있습니다.
rest-API 와 graphql-API 는 몇가지 차이점이 있습니다.
함수 이름의 차이
rest-API는
API 이름이 마치 홈페이지 주소
처럼 생겼습니다.
graphql-API는API 이름이 일반적인 함수
와 같습니다.
응답 결과물의 차이
rest-API
는 응답 결과로 back-end 개발자가 만든 함수에서 보내주는모든 데이터
를 받아야만 합니다.
반면에,graphql-API
는 back-end 개발자가 만든 함수에서필요한 데이터만
골라 받을 수 있습니다. 필요한 데이터만 받는다면 용량이 작아지고, 속도가 빨라집니다.
💡 graphql은 페이스북 개발팀에서 만들었으며 장점은
1. 필요한 데이터만 골라 받을 수 있음
2. 용량이 작아서 속도 빠름
3. 글로벌 서비스에서 사용(페이스북,
이라는 장점을 가지고 있어서 효율적인 통신이 가능하지만 둘다 알아야함!!
JSON은 자바스크립트의 객체 표기법입니다.
객체도 아닌 객체 표기법이란?
백엔드에서 응답을 받을 때, 객체 자체를 주고 받을 수 없기때문에 객체를 문자열로 묶어서 객체를 담은 문자열을 보내는 것입니다.즉, 백엔드에서 응답의 결과물로 넘겨주는 것이 JSON이고, JSON은 객체를 담은 문자열 입니다.
받아온 JSON 데이터는 프론트에서 문자열을 벗겨 객체로 사용하게 됩니다!
API는 크게 4가지 방식으로 구분할 수 있습니다.
- 새로운 것을
생성하는 API
⇒ CREATE- 기존의 것을
조회하는 API
⇒ READ- 기존의 것을
수정하는 API
⇒ UPDATE- 기존의 것을
삭제하는 API
⇒ DELETE
사용방법은 아래와 같습니다.
한장에 정리!
API 명세서
란 API 사용 설명서
입니다.
홈페이지를 만들기 전, Back-end 개발자가 만들어 놓은 API 가 몇 개 있고, 어떻게 구성되어있는지 확인하기 위해 필요합니다.
API명세서는 Back-end 개발자에게 받아야 합니다. Back-end 개발자는 자신이 만든 API를 직접 문서 형태로 작성하거나, swagger 라는 프로그램을 설치해서 만듭니다.
❗️응답 기다리기 ➡️ 동기 (순서대로 코드함수
가 진행된다는 특징이 있습니다.)
❗️안기다리기 ➡️ 비동기 (함수가 순서대로 진행되지 않고 한번에 진행된다는 특징이 있습니다.)
비동기 통신을 동기통신으로 만들어주고 싶다면 명령어 async
/ await
를 사용합니다.
호이스팅은 변수의 선언과 초기화를 분리하여 선언만 코드의 최상단으로 끌어올려주는 것입니다. 따라서, 변수를 정의하는 코드보다 사용하는 코드가 앞서 등장할 수 있습니다. 이러한 문제로 변수는 var
말고 let
,const
를 사용해주고 함수(function)
보다는 화살표 함수
로 사용하자고 배웠습니다.
playground 에서 실습했던 내용의 코드를 vscode에서 적용하기 위해서는 apollo-client라는 도구가 필요합니다.
일반적으로 설치한 도구들을 세팅하는 위치는 _app.js
입니다.
💡 _app.js에 아래와 같이 작성해 줍니다.
💡 vscode에서 apollo-client를 사용하여 graphql-API 요청할 때는
useQuery()
와useMutation()
을 사용해서 통신하면 됩니다. (apollo-client에서 import 해주는 것도 잊지말기!)
// graphql 요청에 필요한 도구 불러오기 import { useMutation, gql } from '@apollo/client'
아래의 CREATE_BOARD를 대문자로 만든 것은 관례입니다.
const CREATE_BOARD = gql` mutation { createBoard( writer: "훈이", title: "안녕하세요!", contents: "내용입니다." ){ _id number message } } `
나의함수는 mutation을 실행하기 위한 이름
입니다.
따라서 aaa 등 아무 이름을 붙여도 괜찮습니다.
하지만 보통 API 이름과 맞춰서 사용하는게 일반적이므로 API 이름과 통일해서 적어주기!
(예시 코드에서는 편의를 위해 나의함수
라는 이름을 사용했습니다.)
// mutation 코드 생성 const [나의함수] = useMutation(CREATE_BOARD)
const [나의함수] = useMutation(CREATE_BOARD); const onClickSubmit = () => { 나의함수({ variables :{ writer: "훈이", title: "안녕하세요!", contents: "내용입니다." } }); } return <button onClick={onClickSubmit}>버튼</button>;
위 코드는 항상 같은 게시물이 등록된다는 문제점
이 있습니다.
위 3번의 CREATE_BOARD 부분이 변경해봅시다!
위 방법은 하드코딩
으로, 같은값만 들어갑니다.
우리는 사용자가 입력한대로 생성해줘야 하기때문에 입력값이 바뀌어야 합니다.
❗️input의 onChange를 이용해 입력받은 값을 state에 저장두었던 것을 활용하여,
입력받은 값을 state에 저장하고 variables에 넣어주면 됩니다.
우선 값을 변경할 수 있도록 기존의 graphql, mutation 코드를 수정해줍시다!
#graphql 코드 const CREATE_BOARD = gql` mutation createBoard($writer: String, $title: String, $contents:String){ createBoard(writer: $writer, title: $title, contents: $contents){ _id number message } } `
// mutation 코드 const onClickSubmit = () => { 나의함수({ variables :{ writer: "훈이", title: "안녕하세요!", contents: "내용입니다." } }); }
❗️즉, graphql에 입력할 데이터는 최종적으로 등록하기 버튼을 눌렀을 때, 실행되는 onClickSubmit 함수에서 실행되는 mutation 에서 넣어 주어야 합니다.
💡mutation에 보내줘야 할 값을 직접 입력하는 방식(3번, 5번 과정)을 우리는 ‘하드코딩’이라고 부릅니다.
rest-API 또는 graphql-API 를 사용해서 요청에 대한 응답으로 받은 객체(JSON)를 변수에 담아서 사용할 수 있습니다.
여기서! 응답 결과를 변수에 담아서 사용하려면! 통신이 완료될 때까지 기다려야 합니다!
async / await
를 활용하여 기다려 봅시다!
// mutation에 동기식 처리 async function onClickSubmit(){ const result = await createBoard({ variables: { writer: "훈이", title: "안녕하세요!", contents: "내용입니다." } }); // 결과물 확인하기 console.log(result); } return ( <button onClick={handleClickPost}>게시물 등록</button> )
기본 형식은 이렇게 됩니다. 화살표 함수로 사용 할때는 async 의 위치를 () 앞에 입력해야합니다.
// 비동기 통신 function 함수명() { // 서버에 요청하는 코드 } // 동기 통신 async function 함수명() { await // 서버에 요청하는 코드 } ---------------------------------------- // 화살표 함수인 경우 const 함수명 = async () => { await // 서버에 요청하는 코드 }
라우터(router)객체
란 페이지 이동과 관련된 기능을 가지고 있는 객체
입니다.
이 객체를 사용해서 A 페이지에서 B 페이지로 이동할 때, "B 페이지로 라우팅한다"
고 말합니다.
/login 페이지는 누가 언제 접속해도 항상 로그인 페이지가 나옵니다.
이러한 페이지로 이동하는 것을"정적 라우팅한다"
고 합니다.
반면, 게시판 상세보기와 같은 경우, 글 번호에 따라서 주소가 변경됩니다.
하지만, 이러한 경우에는 게시글이 100개, 1000개가 넘어가게 되면 각각의 글 번호에 따라 페이지를 100개, 1000개씩 만들어 정적라우팅을 해주기는 어렵기 때문에 이러한 라우팅을 효과적으로 처리하기 위해서
동적 라우팅
을 사용합니다.
/board/1 ⇒ 1번 게시글 상세보기 페이지
/board/2 ⇒ 2번 게시글 상세보기 페이지
/board/3 ⇒ 3번 게시글 상세보기 페이지
/board/4 ⇒ 4번 게시글 상세보기 페이지
... ...이러한 페이지로 이동하는 것을
"동적 라우팅한다"
고 합니다.
[ ]
로 변수명을 만들어주고 진행했습니다!javascript는 작성된 코드가 상단에서부터 순서대로 실행되기 때문에 데이터를 요청하고 응답을 받아오는 동안 화면에 그려질 데이터의 내용이 undefined 이므로 첫 화면이 그려지는 시기에 데이터를 불러오면서 에러가 발생합니다.
이 부분이 효율적으로 실행되기 위해서 화면을 미리 그려놓고 데이터를 그려주기 위해서 조건부렌더링
을 사용합니다.
조건부 렌더링에는 &&연산자, 삼항연산자, 옵셔널체이닝이 있습니다.
data는 동기적으로 받아와야하는 데이터입니다. 하지만 데이터가 오기 전에 이미 return 부분에서 rendering을 해주고 있기 때문에 삼항 연산자를 써서 데이터가 있을 때, 없을 때를 모두 적어줘야 합니다.
data ? data.fetchProfile : undefined
&& 연산자는 데이터가 없을 경우 자동으로 undifined를 반환해줍니다.
&&연산자
는 앞의 값이 참일경우에만 뒤의 값을 보여줍니다.
||연산자
는 앞의 값이 거짓일 경우 뒤의 값을 보여줍니다.
??연산자
는 앞의 값이 빈값(null, undifined)일 경우 뒤의 값을 보여줍니다.
1.
2.
optional-chaing이란 기존의 && 연산자를 쓰면서 길어졌던 코드를 더욱 간결하게 사용하는 연산자 입니다.
optional-chaing은 최신 문법입니다. 무려 ES2020에서 나온 것이죠. 그래서 아직 모르는 사람이 많을 수도 있습니다.
data?.fetchProfile
optional-Chaining은 ? 연산자 앞 객체의 참조가 undefined || null 이라면 undefined를 리턴해줍니다.
위에 있는 삼항연산자, && 연산자와 똑같은 기능을 하지만 훨씬 간단해졌습니다.
mutation이 여러가지 이유로 항상 성공하는 것이 아니기때문에,
성공에 대한 처리와 실패에 대한 처리를 나누어서 작업해야 합니다.
} catch(error) { alert(error.message) // 경고창(실패했습니다.) ==> 백엔드 개발자가 보내주는 실패 메시지 } finally { // 성공, 실패 여부와 상관없이 무조건 마지막에 실행되는 부분 // 필요없다면 생략 가능 } catch 밑 부분에 finally 추가할 수 있음!
* shorthand property
shorthand property는 객체를 정의할 때 객체의 key값과 value 값이 같으면, 각각 표기하지 않고 한 번만 표기하는 것을 의미합니다.const result = await createUseditem({ variables: { createUseditemInput: { name // name: myName remarks // remarks: myRemarks contents. // contents: myContents }, }, }, });
이번주는 리액트를 배웠고, 버튼을 누르면 다른페이지로 이동하게끔 기능도 설정해주었다. GRAPHQL로 값을 저장, Api를 가져오는 기능도 실습해보았다.
수업 들을때는 저게 뭐라는가..? 하면서 일단 잘 듣고있다가 혼자 천천히 생각해보면서 과제를 하면 나름 이해를 잘 했던 것 같다. 정말 여기서 조금만 더하면 죽지않을까 싶을 정도로ㅋㅋㅋㅋㅋㅋㅋㅋ 공부했다. 체력과 시간이 허락한다면 딱 2배만 더 열심히 하고싶다ㅠㅠ
백엔드 분들과 밥먹을 시간이 있었는데 이런저런 이야기 들으면서 '아 나빼고 다 잘하는군..' 싶었다. 그렇지만 나도 열심히 하고있으니까 할 수 있다!! 항상 이런 공부하면 내가 1등해야지 하면서 했는데.. 솔직히 현실적으로 1등은 안될 것 같고ㅎㅎㅎ 적어도 민폐 끼칠 정도만 되지 말자 + 나도 도움줄 수 있는 페어가 되자 라는 생각으로 공부중이다. 이번주도 화이팅이야!!!!
알고리즘 모르는 문제, 게시판 (첫날과제) css 못했음. 꼭 하기 ❗️