[boardId] 폴더 안에서 index.js 파일 안에서는 router.query.boardId
의 값이 나오는 것은 알겠으나 과연 src/componeents/units/board 폴더 안에 <BoardDetail>
에서도 boardId를 알 수 있을까?
boardId 라는 값이 없어도 하나로 합쳐지는 파일이 index.js
로 합쳐지므로(import 되므로) 실행될 때에는 합쳐지고 실행되기 때문에 boardId 값을 그대로 따라간다. 그래서 그 하위 파일(컴포넌트)에서도 boardId 값을 불러 사용할 수 있다.
위에서 [boardId] 폴더 안에서는 detail 컴포넌트에서 boardId 값이 사용될 수 있다는 것을 확인했다.
그렇다면 detail 컴포넌트가 new 폴더 안에서 사용될 때 boardId 값을 출력한다면 어떻게 될까?
결론적으론, undefied 값이 출력된다.
따라서 컴포넌트가 어디에 import 되었는지를 잘 확인하고 router 부분을 사용해야 한다.
router는 주소 관련이라 결국 컴포넌트가 페이지에 합쳐졌을때 실행되는 것이기 때문에 최종 브라우저에 따라 router가 작동할지 여부를 가린다.
emotion 파일에는 자바스크립트 코드가 없으므로 함수를 만들어주어 사용해야 한다. 템플릿 리터럴 사용
export const BlueButton = styled.button`
font-size: ${(props)=> {
return props.rrr;
}};
background-color: ${(props)=> {
return props.qqq;
}};
`
export const BlueButton = styled.button`
font-size: ${props=> props.rrr};
background-color: ${props=> props.qqq};
`
자바스크립트 변수에 true를 넘기고 싶다면 중괄호 안에 true를 써줘야 한다
<BoardWriteUi>
에 props로 mycolor를 넘겨주고 다시 BoardWrite.presenter에서 props로 넘겨주어 BoardWrite.styles에서 받아 함수로 props 값을 삼항연사자로 나타낸다.QUIZ) 작성자, 제목, 내용을 모두 입력하면 버튼이 노란색으로 바꾸기
export default function BoardWrite() {
const [mycolor, setMycolor] = useState(false);
const [나의함수] = useMutation(CREATE_BOARD);
const [writer, setWriter] = useState('');
const [title, setTitle] = useState('');
const [contents, setContents] = useState('');
...
const onChangeWriter = (event) => {
setWriter(event.target.value);
if (writer && title && contents) {
setMycolor(true);
}
};
const onChangeTitle = (event) => {
setTitle(event.target.value);
if (writer && title && contents) {
setMycolor(true);
}
};
const onChangeContents = (event) => {
setContents(event.target.value);
if (writer && title && contents) {
setMycolor(true);
}
};
return (
<BoardWriteUI
...
mycolor={mycolor}
/>
);
}
비교
를 하고 값이 같으면 변경 없고 다르면 변경
이 된다. 바뀐 다음에는 화면이 리렌더링
이 된다.처음에 그려지면 렌더링되고
state가 바뀌면 hook을 제외한 함수, return 등 자바스크립트 코드들이 다시 실행된다. 다시 바뀐 state로 실행되는데 이것을 리렌더링
이라 한다.
import React, { useState } from 'react';
export default function CounterStatePage() {
const [count, setCount] = useState(0);
function onClickCountUp() {
setCount(1);
setCount(2);
setCount(3);
setCount(4);
setCount(5);
}
return (
<div>
<div id='count'>{count}</div>
<button onClick={onClickCountUp}>카운트 올리기!!</button>
</div>
);
}
이것을 해결하기 위해 setState 가 위치에서 변경이 되고 리렌더링이 바로 실행되는 것이 아님을 알았다면 state 값이 아닌
event.target.value
의 값으로 해줘야 한다.
정리
setState를 한다고 그 즉시 state가 변경되는 것이 아니고, 모아두었다가 한번에 처리한다.
그래서 setState를 여러 번 해줘도 중간 값은 임시저장소에 저장해두고 마지막에 해준 값만 출력이 된다.
[]
와 ,
가 사라지고 HTML로 보여진다.위 결과와 동일한 코드
const aaa = ["철수","영희","훈이"].map((el)=><div>{el}</div>)
백엔드에서 받아오는 데이터를 게시물 목록 형태로 보여줄 때에는
.map
을 이용하여 화면에 뿌려주면 된다.
// 백엔드에서 받아온 데이터라고 가정
// 컴포넌트 위에 만든 이유: 컴포넌트 리렌더링 돼도 다시 안만들어짐 => 변하지 않는 상수(emotion, queries..)
const FRUITS = [
{number: 1,title:"레드향"},
{number: 2,title:"사과"},
{number: 3,title:"샤인머스켓"}
]
export default function MapFruitsPage() {
const aaa = FRUITS.map(el=><div>{el.number} {el.title}</div>)
return (
<>
{aaa}
{FRUITS.map(el=><div>{el.number} {el.title}</div>)}
</>
);
}
1. playground에서 한 번 해보고 복사해서 가져오기
2. 변경된 값 $변수로 변환
3. 타입 적어줘야할 것 윗줄에 적어주기
삭제를 클릭하면 onClickDelete가 실행된다
함수가 실행되면 함수 안에 이벤트가 들어오고 event.target하면 태그들이 들어온다.
event.target.id를 가져오고 Html을 가져온 것이므로 string -> number로 타입 변환해주고 사용한다.
삭제버튼 클릭 -> 백엔드에 삭제 요청 api -> 삭제하고 응답 받음 -> 정상적으로 삭제됨
그러나 데이터베이스에만 삭제 되었으나 내 화면에서는 삭제가 되지 않음. 새로고침하면 삭제가 됨.
이를 해결하기 위해 삭제한 이후에 다시 FETCH_BOARDS
를 요청해야 한다.
fetch 했던 것을 다시 fetch한다.
삭제 버튼 클릭 -> 백엔드에 삭제 요청 -> DB에서 삭제 -> refetch 안에 있는 것을 새롭게 다시 요청 -> 화면에 새로 보여줌(삭제된 것 제외)
삭제 버튼 누르면 mutation 1번, query 1번 요청이 간다.
하지만 이렇게 하면 체크박스는 사라지지 않는다
이유는 map은 효율성을 위해서 전체를 기억하고 있다 여기서 새롭게 바꾸기 위해서는 key
를 주어야 한다.
정리
게시물을 수정/ 삭제 했을 때 변경된 데이터가 반영 된 모습을 보여주기 위해서는refetchQueries
를 이용한다.
refetchQueries를 사용하면, mutation 요청이 완료된 후 바로 데이터를 다시 요청해서 refresh된 데이터를 받아올 수 있다.
key는 map에 고유한 값
을 가지고 있어야 한다.
key 값으로는 index 값이 아닌 중복되지 않은 고유한 값을 사용해야 한다.
app.js
는 aaa 폴더 안에 index.js
파일이라는 것과 결과는 동일하다. <>...</>
을 사용했는데 빈 fragment에는 key와 같은 속성을 줄 수 없으므로 이때에는 <Fragment key={el.number}>...</Fragment>
를 사용하면 된다.map의 key 값은 문자열로 주는 것이 좋다.
어떠한 문제가 발생했을 때 어떠한 것의 작동원리를 떠올리면 해결방법이 떠오른다.