▶ 전체 체크박스 선택 시 오류 발생
▶ 전체 데이터 변경 시 개별 항목들(wordLists) 내의 유저 Id와 mysql에서 받아온 data의 UserId가 같아야 하는데, 이를 id로 입력함
const changeStatus = state.wordLists.find(
(v) => v.UserId === data[0].UserId
);
▶ status가 "C"일 때는 checkedWordList 내에 데이터가 채워지나, "A"일 때는 checkedWordList는 아무것도 없어야 함
if (showStatus) {
state.checkedWordList.length = 0;
}
1) 개별 체크박스 클릭 시 체크된 단어 개수 변동
2) 전체 체크박스 클릭 시 단어 개수 변동 및 체크박스 checked 변화하기
status가 변할 때마다 (C <-> A) redux에 적용하는 것이 문제
const data = action.payload; //{id: 1, status: "A"}
const changeStatus = state.wordLists.find((v) => v.id === data.id);
if (changeStatus) {
changeStatus.status = data.status;
}
const onChangeSelected = useCallback((e) => {
const checkboxClicked = e.target;
const wordIndex = e.target.value;
if (checkboxClicked.checked) {
setBChecked(true);
dispatch(changeStatusWordRequest({ id: wordIndex, status: "C" }));
} else if (!checkboxClicked.checked) {
setBChecked(false);
dispatch(changeStatusWordRequest({ id: wordIndex, status: "A" }));
}
}, []);
<input
checked={bChecked}
onChange={onChangeSelected}
value={word.id}
name="checkItem"
type="checkbox"
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
/>
function changeStatusAPI(data) {
return axios.patch(`/word/${data.id}/${data.status}`, {
id: data.id,
status: data.status,
});
}
function* changeStatus(action) {
try {
const data = action.payload;
console.log("data", data);
const result = yield call(changeStatusAPI, data);
yield put(changeStatusWordSuccess(result.data));
} catch (error) {
yield put(changeStatusWordError(error));
console.log(error);
}
}
router.patch("/:id/:status", isLoggedIn, async (req, res, next) => {
// PATCH /word/10/status
try {
await Word.update(
{
status: req.params.status,
},
{
where: {
id: req.params.id,
UserId: req.user.id, //작성자가 본인이 맞는지?
},
}
);
res
.status(201)
.json({ id: parseInt(req.params.id), status: req.params.status });
} catch (error) {
console.error(error);
next(error);
}
});
changeStatusWordSuccess: (state, action) => {
const data = action.payload;
state.changeStatusWordLoading = false;
state.changeStatusWordComplete = true;
const changeStatus = state.wordLists.find((v) => v.id === data.id);
if (changeStatus) {
changeStatus.status = data.status;
}
},
▶ 왜 수정했나?
▶ 핵심은 사용자의 아이디 값(id)를 전달하면 status 전체가 다 바뀌는 것
(status가 모두 A -> C로 변하거나 C -> A로 변함)
{id: 1, english: 'hi', korean: '안녕', type: 'easy', status: "A"},
{id: 2, english: 'hello', korean: '안녕', type: 'easy', status: "A"},
{id: 3, english: 'test', korean: '테스트', type: 'easy', status: "A"}
내용을 checkboxAll이란 체크박스 선택 시
{id: 1, english: 'hi', korean: '안녕', type: 'easy', status: "C"},
{id: 2, english: 'hello', korean: '안녕', type: 'easy', status: "C"},
{id: 3, english: 'test', korean: '테스트', type: 'easy', status: "C"} 변경
[Op.gt]: 0 // id 조건을 > 0 하게 만듦
(콘솔 결과) Executing (default): UPDATE
words
SETstatus
=?,updatedAt
=? WHERE (id
> 0 ORid
= ?) ANDUserId
= ?
(mysql) update
next_engword
.words set status = ? where id= ? or id > 0 and UserId = ?;
npm uninstall nodemon
npm install nodemon
코드 수정 시 콘솔에 이런 식으로 나와야 함
[nodemon] restarting due to changes...
[nodemon] restarting due to changes...
[nodemon] startingnode server.js
const showStatus = wordLists.filter(
(word) => word.status === "C" && word.UserId === UserId
).length;
const allWord = wordLists.filter((word) => word.UserId === UserId).length;
//useEffect에서 조건(filter) 수행 시 useEffect에 들어가는 두 번째 값(배열)을 정확히 지정하기 어려움
//두 번째 값에 wordLists 같은 걸 넣으면 무한 반복
const onChangeAllSelected = useCallback((e) => {
const checkboxClicked = e.target;
const userId = e.target.value;
if (checkboxClicked.checked) {
setBChecked(true);
dispatch(changeStatusWordAllRequest({ status: "C", userId: userId }));
} else if (!checkboxClicked.checked) {
setBChecked(false);
dispatch(changeStatusWordAllRequest({ status: "A", userId: userId }));
}
}, []);
return (
<input
checked={showStatus > 0 ? true : false} // checked={bChecked}로 넣으면 아무것도 체크 안 되어 있어도 체크되어 있다고 나옴
onChange={onChangeAllSelected}
value={UserId}
name="checkItem"
type="checkbox"
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
/>
전체 선택 / 해제
</div>
<p>
체크된 단어 개수 :{showStatus}/{allWord}
</p>
)
function changeStatusAllAPI(data) {
return axios.patch(`/word/all/${data.userId}/${data.status}`, {
status: data.status,
userId: data.userId,
});
}
function* changeStatusAll(action) {
try {
const data = action.payload;
const result = yield call(changeStatusAllAPI, data);
yield put(changeStatusWordAllSuccess(result.data));
} catch (error) {
yield put(changeStatusWordAllError(error));
console.log(error);
}
}
router.patch("/all/:userId/:status", isLoggedIn, async (req, res, next) => {
// (전체 수정) PATCH /word/status/1(userId)
try {
await Word.update(
{
status: req.params.status,
},
{
where: {
[Op.or]: [{ id: { [Op.gt]: 0 } }, { id: req.params.userId }],
UserId: req.user.id,
},
}
);
const fullWord = await Word.findAll({
where: { status: req.params.status },
});
console.log("fullWord", fullWord);
res.status(200).json(fullWord); //game쪽에 정보 전달하기 위함
res
.status(200)
.json(fullWord);
} catch (error) {
console.error(error);
next(error);
}
});
const data = action.payload;
state.changeStatusWordLoading = false;
state.changeStatusWordComplete = true;
const changeStatus = state.wordLists.find(
(v) => v.UserId === data[0].UserId
);
const showStatus = state.wordLists.find(
(v) => v.UserId === data[0].UserId && v.status === "C"
);
if (changeStatus) {
state.wordLists.map((word) => {
word.status = data[0].status;
state.checkedWordList.length = 0;
state.checkedWordList = state.checkedWordList.concat(data);
});
}
if (showStatus) {
state.checkedWordList.length = 0;
}
▶ find
주어진 판별 함수를 만족하는 첫 번째 요소의 값을 반환합니다. 그런 요소가 없다면 undefined를 반환
▶ filter
주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환
▶ map
배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환