게시글 목록 그리기 :map사용.
page 부분. 로그인여부,( 권한분기 ) 부분이 이 부분에 존재하게됨. 검증부분로직을 페이지에 넣게 될것.
(목록, 상세페이지 누구등 누구나 볼 수 있는 페이지 마이페이지 등 로그인한사람만 볼 수 있는 페이지)
컴포넌트 : 어디서든 importrksmd.
다만.. 컴포넌트의 경우....... 어디서 import가 될것인지를 보고 사용.
router.query.boardId가 있는(대괄호 폴더 있는) 곳에서 import하여 사용되면 실행됨.
그러너 import하는데, router.query.boardId가 없으면 에러남.
==> 하나로 합쳤을때의 결과를 예측해 생각하기. 주소창 어디에 들어갈지...
(주소창에 주소 입력하고 실행시에 합쳐서 한방에 실행되니.)..
주소가 들어갈부분이 없다면 router.query.boardId를 하면 에러남.
(/boards/new 의 경우)주소에 boardId가 들어가 있으면 해당 rouer.query.boardId가 잘 실행되니 에러 안남.
활성화 버튼 ==>필수 input이 입력되었을때 버튼색 활성화.
setState원리알기.
==>
presenter부분도 style컴포넌트(emotion)의 부모.
보내주면, 해당 스타일 부분의 벡틱안에서 props를 받을 함수가 있어야하니 함수를 만들어주고 그 안에서 받는다.
==> 벡틱안에서 ${} 하고작성 ==> 탬플릿 리터럴!!!
const aaa = 3
안녕하세요 ${aaa} 반갑습니다
초록색 부분은 다 컴포넌트...
버튼 활성화 여부 => 실무에서는 활성화라는 의미로 isActive등으로 사용하니 isActive가true일때의 색변화 주기.
background-color: ${(props) => props.isActive === true ? "yellow" : ""};
이렇게 적지 않아도 true면 앞에꺼 false면 뒤에꺼가 나옴.
background-color: ${(props) => (props.isActive ? "yellow" : "")};
state 사용해 해보기
isActive가 전달되고, 전달되어 container에서 presenter로 --> presenter에서 isActive라는 키로 value는 props.isActive 로 해서 emotion으로...
state 동작과정.
setState의 함수가 실행되면 기존 state와 비교하고,
1. 다를경우 state의 값을 바꿈
2. 바뀐것으로 화면을 다시 그림(다시그림 = 리랜더링(다시실행))
이 과정에서 함수, 변수 등이 다시 실행됨. => 비효율적. 뒤에서 최적화 배우기.
==> 이렇다보니 만약 setState가 한번에 여러개 있으면... 바뀌면서 화면이 다시 그 횟수만큼 다시 그려주는 방식이 되는데,
결국 눈에 보이는것은 마지막부분에서 바뀐값!
굉장히 비효율적.
따라서 이 경우들의 이 무의미한(불필요한) 리랜더링 방지하기위해 setState는 일단 만나면 임시 저장공간에 저장해놓고, 내려가서 다시 바뀐것 저장... --> 함수가 끝나면 최종적으로 마지막것으로 화면을 다시그리는 방식으로 작동함.
==> state가 바뀌면 일단 임시 공간에 저장된 후 , 해당함수가 끝났을때 반영됨.
따라서 isActive로 버튼 활성화를 하려할때 두글자 이상 적어야 state에 반영되기때문에(함수가끝나기 전에는 임시 저장소에 저장됨. 함수가끝나고서 값이 변경되면 그것은 바로 반영??) 지금입력한 값을 사용하여 작성해야 적용이된다.
목록보기:
유지보수가 좋은 map사용.(for문이 약간 빠르긴하지만 유지보수가 좋은 map.. 사용)
상황에 따라 다르지만 일반적으로 유지보수가 좋은 map을 주로 사용.
map =>
배열.map((el)=>(el+'어린이')
el에는 배열의 각 요소가 들어가고 el + '어린이'부분에서는 각요소에 '어린이' 가 붙은 형태의 배열이 만들어짐
이 소괄호를 생략할 경우 객체의 중괄호가 아닌 화살표함수의 중괄호가되어버리니 이 경우에는 소괄호 생략하면 안됨. 다른 경우의 소괄호는 생략가능.
화살표함수의 중괄호 => 함수를 의미
==> 중괄호와 return 사이에 아무것도 없을 시 소괄호로 바뀌며, 이 소괄호도 별다른 의미가 없다면 생략가능!!'
만약 return시 객체를 리턴할때 ==> 이경우에는 소괄호 생략못함.(생략시 앞에서도 언급했듯 이 중괄호가 함수의 중괄호가 되어버림)
map 익히기.
map 과 html연결
map안에서 html태그 사용가능.
const a = ["c","d","e"]
a.map{(el)=><div>{el}<div>}
==> el에 각 요소가 들어가 [<div>c<div>,<div>d<div>,<div>e<div>]
이런 배열형태가 출력된다고 보면됨.
fruits라는 배열이 있고 그 데이터를 map으로 뿌려본다.
const FRUITS = [ { number: 1, title: "레드향" }, { number: 2, title: "샤인머스켓" }, { number: 3, title: "산청딸기" }, { number: 4, title: "한라봉" }, { number: 5, title: "사과" }, { number: 6, title: "애플망고" }, { number: 7, title: "딸기" }, { number: 8, title: "천혜향" }, { number: 9, title: "과일선물세트" }, { number: 10, title: "귤" }, ]; <div> {/* 3. 실무 효율적인 예제 */} {FRUITS.map( ( el // 실무방법: 변수에 담아 사용하지 않고 html에서 바로작성(jsx에서 js를 적기위해 중괄호 필요.) ) => ( <div> {el.number} {el.title} </div> ) )} </div>
const mystyles = { margin:"10px" }
// 이런 객체형태로 작성하여 객체 이름이 바인딩되어 style={mystyles} 이렇게 작성되는 형태인데, 번거로우니 뒤에 중괄호 부분만 잘라 넣은형태가
style={{ margin: "10px" }}
삭제버튼을 누르면 해당 게시물 삭제하기 ==> 버튼의 아이디를 해당게시물번호로 주고, 뮤테이션 날릴때 event.targert.id를 이용해 해당 id인 게시를 번호를 사용함.
문제 : 삭제버튼을 눌렀을때, 삭제 완료 메세지 보이나, 새로고침 전까지 화면에 반영되지 않음.(실제 삭제는 됨.)
새로고침시 --> 다시 fetchBoards를 요청 --> 삭제 반영된 것으로 화면이 나옴.
==> 비효율적. 자동으로 새로고침되게 해줘야함. 즉, 다시 재요청.(refetch === fetch를 다시하자)
refetchQueries:[{query:리패치할 쿼리명}] =>배열 형태이고, 따라서 여러개 작성 가능.
map에는 key라는 게 있음. key를 사용해 각각이 독립된것이라는것을 알려줌. (즉, 다음 map으로 뿌려질것과 다른것이라고 알려줌)
기존 개시글 각 줄에 체크박스를 같이 넣어주었는데, key를 인덱스로 주고 삭제하니 체크된 체크박스는 그대로임. ==>
key에 index를 사용할 경우, ==> 중복되지 않는 값이지만 , 삭제하면서 아래것이 위로 올라와 해당 인덱스가 유지됨. ==> 예기치 못한 변수들 발생.....
** div는 블록요소로 다음줄로 내려감!
table 태그 사용시 제목 행은은 thead로감싸고 tr이 하나의 행(가로) 그안의 내용물을 td로. 그리고 아래 내용부분은 tbody로 감싸고 tr 이 하나의 행이니(row) 그안의 내용물은 역시 td로 각각....
<table>
<thead>
<tr>
<td>제목</td>
<td>내용</td>
<td>날짜</td>
</tr>
</thead>
<tbody>
<tr>
<td>제목입니다</td>
<td>내용입니다</td>
<td>날짜입니다</td>
</tr>
</tbody>
</table>