해결된 질문
23.09.26 18:17 작성
·
297
1
안녕하세요, 좋은 강의 감사드립니다. 제가 좋아요 기능구현을 해보고 있는데,
클릭이 되면 state(clicked)를 통해 true로 만들어서 빨강색으로 만들고 1를 추가시키고 다시 클릭하면 false가 되면서 검게 되고 1을 감소하게 하는 기능을 구현하려고 하는데요. 각각 빨/검 1추가시키기는 되는데 둘이 합치려니까 1을 올리면서 리렌더링이 되고 clicked라는 스테이트가 바로 false로 초기화되버리는것 같습니다. 혹시 방법이있을까요? 뭐라고 검색해야 할지 감이 잘안잡혀서 질문남깁니다.
const Heart = ({ pageId, id, currentIndex, postId, }) => {
const dispatch = useDispatch();
const { coursePosts } = useSelector((state) => state.coursePost);
const { clicked, setClicked } = useState(false);
const heart = coursePosts[currentIndex].CourseReview[id].heart;
const onClickHeart = () => {
if (!clicked) {
dispatch(coursePostActions.clickCourseReviewHeart({ pageId, postId }))
} else {
dispatch(coursePostActions.clickCourseReviewHeartAgain({ pageId, postId }))
}
setClicked(!clicked);
}
return (
<button type="button" onClick={onClickHeart} className={clicked === true ? styles.active : ""}>
<FontAwesomeIcon icon={faHeart} />
<span>{heart}</span>
</button>
);
};
export default CourseReviewItems;
const coursePostSlice = createSlice({
name: "coursePost",
initialState,
reducers: {
clickCourseReviewHeart(state, action) {
const postIndex = state.coursePosts.findIndex((v) => v.id === Number(action.payload.pageId));
const reviewIndex = state.coursePosts.findIndex((v) => v.id === action.payload.postId);
state.coursePosts[postIndex].CourseReview[reviewIndex].heart += 1
},
clickCourseReviewHeartAgain(state, action) {
const postIndex = state.coursePosts.findIndex((v) => v.id === Number(action.payload.pageId));
const reviewIndex = state.coursePosts.findIndex((v) => v.id === action.payload.postId);
state.coursePosts[postIndex].CourseReview[reviewIndex].heart -= 1
}
}
답변 2
0
2023. 09. 26. 23:17
const CourseReviewItems = ({ coursePostReviewPosts, post, currentIndex, pageId, postId }) => {
const starRendering = (star) => {
const stars = [];
for (let i = 0; i < star; i++) {
stars.push(<span key={`fill_stars_${i}`}><FontAwesomeIcon icon={faStar} className={styles.fill_stars} /></span>)
}
for (let i = 0; i < 5 - star; i++) {
stars.push(<span key={`empty_stars_${i}`}><FontAwesomeIcon icon={regStar} className={styles.empty_stars} /></span>)
}
return stars
}
return (
<>
<div className={styles.dt_review_item}>
<div className={styles.dt_review_top}>
<div className={styles.dt_review_profile_cont}>
<figure>
<Image src={profileImg} alt="닉네임" />
</figure>
<div className={styles.dt_review_profile}>
<div className={styles.dt_review_star_cont}>
<div className={styles.dt_review_star}>
{starRendering(coursePostReviewPosts.point)}
</div>
<span>{coursePostReviewPosts.point}</span>
</div>
<div className={styles.dt_review_txt}>
<span className={styles.dt_review_user}><b>{coursePostReviewPosts.User.name}</b>{`(${coursePostReviewPosts.User.id})`}</span>
<b> · </b>
<span>{coursePostReviewPosts.date}</span>
</div>
</div>
</div>
</div>
<div className={styles.dt_review_content}>
<p>{coursePostReviewPosts.content}</p>
</div>
<div className={styles.dt_review_bottom}>
<Heart id={post} pageId={pageId} currentIndex={currentIndex} postId={postId} />
</div>
</div>
</>
);
};
const Heart = ({ pageId, id, currentIndex, postId }) => {
const dispatch = useDispatch();
const { coursePosts } = useSelector((state) => state.coursePost);
const [clicked, setClicked] = useState(false);
const heart = coursePosts[currentIndex].CourseReview[id].heart;
console.log(clicked)
const onClickHeart = () => {
// if (!clicked) {
// dispatch(coursePostActions.clickCourseReviewHeart({ pageId, postId }))
// console.log("true")
// } else {
// dispatch(coursePostActions.clickCourseReviewHeartAgain({ pageId, postId }))
// console.log("false")
// }
setClicked((p) => !p);
console.log("dfdf", clicked)
dispatch(coursePostActions.clickCourseReviewHeart({ pageId, postId }))
}
console.log(clicked)
return (
<button type="button" onClick={onClickHeart} className={clicked === true ? styles.active : ""}>
<FontAwesomeIcon icon={faHeart} />
<span>{heart}</span>
</button>
);
};
export default CourseReviewItems;
0
2023. 09. 26. 22:58
리액트는 리렌더링된다고 state가 초기화되지는 않습니다. 컴포넌트 자체가 없어졌다가 새로 만들어져야지만 state가 초기화됩니다.
2023. 09. 26. 23:14
늦은시간에도 답변달아주셔서 감사합니다. 네네 오타 발견하고 [] 로 고쳐서 진행중입니다. 신기한게 dispatch 부분이 없으면 setClicked가 잘 작동하는데 dispatch랑 같이 쓰면 작동을 안합니다. 혹시나해서 setclicked다음에 console.log해보고 dispatch뒤에도 콘솔 넣어서 clicked값을 확인을 해봐도 전부다 false로만 뜨네요. 작동을 안하고있네요..
2023. 09. 26. 23:35
이유를 알것 같네요. Heart 가 map function 안에 있는데, dispatch를 하게되면 배열 전부가 한번 돌게되네요.
쉽게말해서 console.log(heart)를 하고 글 하나를 클릭하면 다른글들의 heart 값들도 출력이됩니다. (하트갯수는 그 누른애만 잘 작동합니다.) 현재 관련해서 setState가 작동을 잘안하는거같네요..
2023. 09. 27. 00:12
setClicked같은 set 시리즈는 바로 적용되는 게 아니라서 그 뒤에 console.log를 한다고 해서 값이 바뀌지 않습니다.
2023. 09. 27. 00:15
python 위주로 머신러닝쪽 개발하다가 이번에 프론트엔드 프로젝트 하나 들어와서 하고있는데 비동기는 참 tricky하네요... 감사합니다. 한번 데브툴로 해결해보겠습니다
2023. 09. 26. 22:53
빠른답변감사드립니다. 계속 콘솔로그 찍어보는데도 false로만 잡히네요. 제가 생각한대로 dispatch 불러오면서 함수 전체를 리렌더링시키고 그래서 초기값인 usestate(fasle)된게 계속 초기화되서 false로만 찍히는걸까요?