[React] useState의 초기값을 props의 값으로 설정하기

Isabel·2022년 5월 13일
0

프로젝트 중 community 페이지를 구현하는데 해당 각 게시물을 클릭하면 상세페이지로 넘어가고 각 게시물의 내용을 props로 넘겨주었다. 그런데 이때 기존에 좋아요 혹은 북마크 했다는 불리언 값들을 useState의 초기값으로 지정하려고 하였으나 잘 되지 않았다.

const DetailCommPost = (props) => {   
    const dispatch = useDispatch();
    const history = useHistory();
    const params = useParams().postId;
    const isLogin = sessionStorage.getItem('token');
    const post = props?.postList;
    const postLike = post?.postLike;
    const bookmarked = post?.postBookMark;

    const [like, setLike] = React.useState(postLike);
    const [bookmark, setBookmark] = React.useState(bookmarked);
  
  	console.log(like);  //false
	console.log(postLike);  //true
  
    const toggleLike = () => {
        if (like === false && isLogin) {
        setLike(true);
        dispatch(postActions.likeDetailPostDB(post.postId));
        } else {
        setLike(false);
        dispatch(postActions.likeDetailPostDB(post.postId));
        }
    };
    const toggleBookmark = () => {
        if (bookmark === false && isLogin) {
        setBookmark(true);
        dispatch(postActions.bookmarkDetailPostDB(post.postId));
        } else {
        setBookmark(false);
        dispatch(postActions.bookmarkDetailPostDB(post.postId));
        }
    };

    useEffect(() => {
        dispatch(postActions.getDetailPostDB(props.postId));
    }, [like, bookmark]);

if(!post) {
    return (
        <div></div>
    )
}
    return (
        <React.Fragment>
            <Grid >
                <Grid width="100%" >
                    <Grid><Text>{post?.postType}</Text></Grid>
                </Grid>
                <Grid  
                _onClick={()=>{
                    history.push(`/community/${post.postId}`)}}>
                    <Grid>
                        <Text size="large">{post?.postTitle}</Text>
                    </Grid>
                    <Grid>
                        <Image type="circle" size="24px" imgUrl={post?.profileImgUrl}/>
                        <Text>{post?.nickname}</Text>
                        <Grid><Text>{post?.postRecentTime}</Text></Grid>
                    </Grid>
                    <Grid><Text>{post?.postContent}</Text></Grid>
                    {post?.postImgUrl? 
                    <Grid width="100%" >
                        <Image type="rectangle" imgUrl={post.postImgUrl}/>
                    </Grid>: null}
                </Grid>
                {/* bottom part - 좋아요, 댓글, 북마크 */}
                <Grid width="100%" margin="20px 0px" position="relative">
                    <Grid is_flex >
                        {like===true? 
                            <FaHeart 
                            onClick={()=> toggleLike()} style={{width:"20px", height:"fit-content", color:"#FA4D56"}}/> : 
                            <FaRegHeart onClick={()=>toggleLike()} style={{width:"20px", height:"fit-content"}}/>
                        }
                        <Text margin="0px 8px" size="base"  color="#6F6F6F">{post?.postLikeCount}</Text>
                        <FaRegComment  style={{width: "20px", height:"fit-content"}} /><Text margin="0px 8px" size="base" color="#6F6F6F">{post?.commentCount}</Text>
                    </Grid>
                    <Grid position="absolute" top="0px" right="0px" >
                        {bookmark===true? 
                            <FaBookmark onClick={()=>toggleBookmark()} style={{width: "20px", height:"fit-content", color:"#0AAF42"}}/> : 
                            <FaRegBookmark  onClick={()=>toggleBookmark()}style={{width: "20px", height:"fit-content"}} />
                        }
                    </Grid>
                </Grid>
            </Grid>
        </React.Fragment>
        
    )
}

export default DetailCommPost;

내가 생각하기에는 props에서 딸려온 postLike를 like의 초깃값으로 정해줬으니 둘이 똑같아야 했다. 하지만 계속 값이 달랐다.

해결방안: useEffect 활용
처음 like를 선언할 때 props가 값을 가져오는 순서와 일치하지 않아 발생한 일인 것 같았다. 그래서 useEffect를 활용하여 props의 값이 달라졌을 때, useEffect를 실행시켜 setLike로 like의 값을 props.postLike와 같아지게 하였다.

useEffect(() => {
        dispatch(postActions.getDetailPostDB(postId));
        setLike(postLike);
        setBookmark(bookmarked);
    }, [post.postId, like, bookmark]);

상세페이지를 불러올 때에도 props를 통해서 dispatch해서 해당 상세페이지를 불러왔는데, 이 때도 props가 넘어오는 속도와 dispatch하는 순서가 맞지 않아서 전에 봤던 게시글이 불러져오기도 하였다.

이 부분에 대해서는 props에 포함된 postId로 dispatch하여 데이터를 불러오지 않고, useParams훅을 사용하여 즉시 데이터를 불러올 수 있게 하였다.

0개의 댓글