
검색 결과가 100개가 넘는다면 페이지네이션도 리페치 해줘야하므로 BoardsCount도 리페치를 해준다.

서치바 컴포넌트 안에서 변경이 일어나면 변경된 인풋으로 리페치가 실행돼서 목록으로 다시 보여지게 된다.
전체 페이지 개수도 재계산이 된다.

사용자가 사용할 수 없는 유형의 시크릿 코드를 붙여줘야한다.




실제로 이렇게 실행을 하게 되면 123이 aaa로 넘어가고 aaa.count가 123으로 나타나게 된다.

사실 함수형 컴포넌트는 함수였다. 그냥 이렇게 실행하면 된다.

우리가 공식처럼 props라고 썼지만 그렇게 써줄 필요가 없다. aaa는 함수에 들어가는 매개변수다.
컴포넌트 형태를 함수로 실행하는 형식으로 바꿔서 실행을 하면 실행이 된다.

훈이라는 인자가 aaa라는 파라미터에, 2라는 인자가 bbb라는 파라미터에 들어가게 된다.
// 훈이는 2 입니다.

index라는건 자동으로 1씩 증가하는 것
map안은 함수고 el, index는 함수에 들어가는 매개변수,
철수, 0은 인자들이고 인자들이 매개변수에 들어가게 되는 것이다.
el이 꼭 el일 필요가 없다. index가 index일 필요가 없다.

사실 el, index같은 건 없었다.

// 철수
말이 index지 철수가 index라는 매개변수로 들어오게 된다.

prev또한 매개변수다. prev일 필요가 없다.


writer 부분이 writer일 필요가 없다. 결국 writer도 변수였던 것

앞에있는 writer는 백엔드로 가는 writer이므로 변경하면 안되고,
$가 붙은 변수이름은 지정해줄 수 있고 이름만 통일시키면 된다.

두번 써줬어야 했던 이유 ? graphql은 한번에 묶음배송처리를 할 수 있었기 때문에
변수 이름을 나눠줄 수 있었다.
rest-Api였다면 Api요청을 할 때마다 계속 써줘야함

createBoard는 그룹이름이었고 아무거나 바꿔도 상관없다.
<실습>

props가 아닌 aaa로 바꿔도 되는 이유 ? 함수이기 때문!

함수로 바로 return 가능!

정상출력
props로 받는 부분은 함수의 매개변수이다보니 굳이 props라는 단어를 쓸 필요가 없었다.
아무거나 이름을 바꾸어도 상관이 없었다.

map은 각각의 실행결과를 리턴한다.
forEach가 map보다 빠르다.

el과 index가 이름을 바꿔도 정상실행

화살표 함수가 아닌 함수 선언식으로 해도 정상실행


el과 index의 이름을 바꾸면 index에 철수, 영희, 훈이가 들어감

prev는 결국 함수의 매개변수였다.


정상작동
기존 rest에서는 한 페이지에서 게시글 목록, 상품목록, 프로필, 세번을 각각 따로 요청을 해줘야하지만 graphql은 한번에 묶음으로 가져올 수 있었다. => 이것을 언더페칭이라 한다.
rest-api는 언더페칭의 문제가 있다.
방금처럼 한페이지에서 게시글,프로필,계좌정보를 다 보여줘야하는데 한번에 하나씩밖에 가지고 올 수 없다. 내가 원하는건 네개인데 한개씩 밖에가져올수 없다.
즉 내가 원하는 것보다 under(아래)로 가져올 수 있다.
graphql은 한번에 전부 다 가져올 수 있는 묶음배송이 가능하다.
rest-api는 내가 원하는 건 writer와 title인데 contents 등도 다 가져와야한다.
내가 원하는 것보다 더 over해서 가져오게 되는 것이 오버페칭이다.
이 문제를 해결한 게 graphql이다.
만약 핸드폰번호를 검증할 때 if문과 for문을 사용해서 검증을 하려하면 너무 복잡해진다.
이것을 정규표현식으로 사용하면 훨씬 간단하게 표현할 수 있다.
정규표현식을 사용하려면 슬래시를 양쪽에 넣어준다.

apple이 사용자에게 입력받은 데이터가 되고,
/apple/이 조건으로 검증하는 부분이 된다.
사용자가 입력한 apple이라는 값이 /apple/이 맞는지 검증을 한다.
입력값과 조건이 맞으므로 true를 반환

다르면 false를 반환
a는 a뿐만 아니라 모든 숫자, 모든 문자가 가능하다. 한 문자 또는 숫자를 의미 = w
w의 원래의 기능을 탈피해줘 = \ (역슬래시)


한 문자가 아니라 맞는 식이 있다면 true를 반환하기 때문에
정규표현식이란 시작과 끝을 정해주지 않으면 이 내용이 중간에 포함만 되어있으면 true가 나온다.

^ , $로 시작과 끝을 정해주어야 함!

+를 넣어주면 1개 이상이라는 의미가 된다.
없거나 1개일 때는 => ?
1개거나 그 이상일 때는 => +
없거나 1개거나 그 이상이거나 => *

1글자 이상의 문자 + @ + 1글자 이상의 문자 + . + 1글자 이상의 문자

이메일이 아닌 식도 true가 나옴
. 은 모든 것이 다 들어가도 좋음을 의미

역슬래시가 붙으면 의미를 탈피하기 때문에 문자열 . 을 의미하게 된다.

^와 $를 이용해 시작점과 끝점을 잡아준다

w를 이용하면 문자도 들어갈 수 있기 때문에 사용하면 안된다.

d는 그냥 문자열 d이기 때문에 역슬래시 d를 이용해 숫자만 들어갈 수 있는 조건 digit을 만들어준다.


중괄호로 문자의 개수를 정해줄 수 있다.
앞자리와 중간자리에는 3글자, 4글자가 들어올 수 있으므로 3, 4를 지정해준다.

대괄호를 사용하면 "문자만"을 의미한다.

역슬래시 s는 스페이스바, 공백을 의미한다.

페이지 안에는 여러개의 컴포넌트가 조립되어서 나타나고 있다.
가끔씩 state들이 공유되었으면 하는데, 우리는 props를 넘겨주어서 진행했었다.
=> 프롭스 드릴링 (프롭스를 뚫고 내려간다)
너무 비효율적으로 보인다.
모든 컴포넌트에서 공유할 수 있는 공통 state가 있으면 좋겠다.
한방에 다 뽑아서 쓸 수 있으면 좋겠다.
이것을 global-state라고 부른다. 이것이 초창기에는 redux를 설치해서 사용을 했었다.
예전에는 react하면 redux 하는 공식처럼 사용이 됐었다.
이게 너무 복잡해서 세팅하는 시간도 오래걸리고 만드는 시간도 오래걸리고 노가다성으로 코딩해야되는 부분이 너무 많았다.
그래서 그 이후에 이것을 개선해서 mobX가 나오고, swr이 나오고...
전에는 state란 state는 redux에 담아두었었는데,
api를 저장해두는 global-state를 두고, 일반 global-state로 나눈다.
api는 대표적으로 rest-api / gql 로 나누어진다.
일반 global-state부분에는 react 자체에서 제공해주는 context-api를 두었다.
하지만 context-api에 문제가 있었고 recoil이 만들어지게 되는데 recoil은 context-api에서 만들어졌다.

아폴로 클라이언트를 통해서 백엔드에 데이터를 요청을 하면
useQuery를 받아오게 되면 캐시 state에 저장이 된다.
그 state가 undefined였던 data에 들어가면서 fetchBoard가 된다.
data가 바뀌면 컴포넌트는 리렌더가 됨.
결국 State와 같은 기능을 한다고 했었다.

fetchProduct가 이미 캐시 스테이트(글로벌 스테이트)에 저장이 되어있으면
백엔드에 또 요청을 할 필요없이 여기서 꺼내서 오면 된다.
이것을 fetchPolicy의 cache-first라고 한다.
캐시 스테이트에 저장이 안되어있으면 데이터를 받아오고,
캐시 스테이트에 저장이 되어있으면 바로 꺼내온다.
network-only : 캐시에 가지 않고 무조건 백엔드에 가서 데이터를 받아옴
cache-only: 백엔드에서 받아오지 않고 캐시에서만 받아옴
가장 안정적인 것은 cache-first!
cache-and network: 캐시에 있는 것을 가지고 온다고 하더라도 일단 api요청은 해보긴 한다. 그리고 그 둘을 비교해본다.
** 아폴로 클라이언트 Docs에 잘 나와있다.
이런것들이 이미 다 만들어져있다보니 훨씬 효율적이다.

그래서 cahce-state와 recoil-state로 나눈다!
둘 간의 차이는 api로 받아오느냐, 안 받아오느냐의 차이다.
나만의 스테이트도 아폴로 스테이트에 저장가능하지만 헷갈리므로 실제로는 나눠서 쓰는 경향이 있다.
api용, api이외의 용
결국 글로벌 스테이트가 2개, 아폴로 캐시스테이트, 리코일 스테이트로 나눠져있다!
<recoil 실습>
yarn add recoil

props 드릴링 없이 recoil 스테이트를 isEdit=true로 주어 내려받게 해본다.
recoil state를 store(저장소) 라고 한다.

원래 우리가 했었던 프롭스 드릴의 형태
Atom은 어디서든 뽑아쓸 수 있는

글로벌 스테이트는 하나밖에 없기 때문에 key값으로 구분
이 state의 초기값은 false

isEditState를 useRecoilState에 불러와 사용
isEdit라는 변수는 모든 페이지마다 값이 달랐는데 글로벌 스테이트를 꺼내옴으로써 같은 값으로 정의할 수 있다.

_app.tsx
아폴로 클라이언트가 모든 컴포넌트들에 감싸져있다.
Recoil도 마찬가지로
서로가 서로간의 글로벌 스테이트를 뽑아쓸 수 있게끔 만들어준다.
