sns 프로젝트

트위터 리트윗 기능 구현하기

우주속공간 2024. 1. 22. 03:29

 

📁 리트윗 기능 미리보기

 

 

 

 

리트윗 기능 구현 과정을 간단하게 정리해보자면 다음과 같다.

 

프론트

  • 리트윗 버튼 생성
  • retweet, quote tweet 기능 함수 생성
retweet  : saveTweet API로 리트윗 대상 트윗 아이디 추가해서 보내기.(리트윗 게시물 아이디로 나중에 대상 리트윗 데이터 가져옴)
quote tweet : 클릭시 모달창 오픈, 클릭된 트윗 게시물 아이디 인덱스를 기준으로 addTweet 컴포넌트로 데이터 넘겨줌.
  • 리트윗 창 openRetweet 기능 생성(클릭시 state값 변경)

 

백엔드

 

트윗 데이터를 저장하는 saveTweet API 에서 리트윗 게시물 아이디를 저장할 수 있는 reply_tweet_id 추가함 

 

 

실제 구현한 코드


 

openRetweet 기능

 

➡️ 백엔드에서 데이터를 가져올때 retweet_opened=false인 값으로 가져옴.

➡️ 리트윗 버튼을 클릭하면 데이터 인덱스값을 기준으로 retweet_opened 값에 접근해서 현재값과 반대되는 값으로 바꿔줌. (예시. false인 경우 true로 변경하여 버튼이 오픈되게 변경해줌)

const openRetweet = ({ tweet_id, open, index }: any) => {
    data[index].retweet_opened = open === false ? true : false;
    setGetData([...data]);
  };

 

 

 

 

retweet, quoteRetweet 기능

 

  • retweet

1. 리트윗 게시물 아이디, 내용은 빈값, 유저 데이터, 태그를 retweet으로 saveTweet API보내기

2. “select”키로 저장된 react query state값을 초기화 시켜줘서 업데이트된 데이터로 다시 들고오게 함.

 

  • quoteRetweet

1. 클릭하면 새로운 tweet을 저장하는 모달창 오픈됨.

2. 리트윗되는 게시물을 인덱스를 기준으로 addTweet(tweet 생성 컴포넌트)에 prop값으로 보내줌.

3. openRetweet을 실행시켜서 retweet 버튼 창을 닫음.

 

const retweet = (tweet_id: number) => {
    customAxios
      .post("/saveTweets", {
        reply_tweet_id: tweet_id,
        content: "",
        user_id: id,
        tag: ["retweet"],
      })
      .then((res) => {
        customAxios
          .get("/getTweets/select", {
            params: { getCurrentPage },
          })
          .then((result: any) => {
            queryClient.invalidateQueries(["select"]);
          });
      });
  };

  const quoteRetweet = ({ t, i }: any) => {
    setModalIsOpen(true);
    setNowData(data[i]);
    openRetweet({
      tweet_id: t.tweet_id,
      open: t.retweet_opened,
      index: i,
    });
  };

 

 

 

 

 

 

리트윗 버튼 

 

retweet_opened 값에 따라 버튼 보여주기 유무가 변경됨.

true일경우 retweet, quote retweet 버튼을 보여주면서 클릭시 각 기능이 실행됨.

<div className=" ">
                        <img
                          className="w-6 h-4 pl-2"
                          alt="#"
                          src={"/assets/retweet.png"}
                          onClick={(e: any) => {
                            openRetweet({
                              tweet_id: t.tweet_id,
                              open: t.retweet_opened,
                              index: i,
                            });
                          }}
                        />
                        <div key={t.write_date}>
                          {t.retweet_opened ? (
                            <div className="ml-2 flex flex-col border-2 rounded border-stone-200">
                              <button
                                className="p-2 hover:bg-slate-100 rounded "
                                onClick={() => {
                                  retweet(t.tweet_id);
                                }}
                              >
                                Retweet
                              </button>
                              <button
                                className="p-2 hover:bg-slate-100 rounded"
                                onClick={() => {
                                  quoteRetweet({ t: t, i: i });
                                }}
                              >
                                Quote Tweet
                              </button>
                            </div>
                          ) : (
                            modalIsOpen && (
                              <Modal
                                className=" commentModal"
                                isOpen={modalIsOpen}
                                ariaHideApp={false}
                              >
                                <div className="list">
                                  <button
                                    onClick={() => setModalIsOpen(false)}
                                    className=" text-end"
                                  >
                                    X
                                  </button>
                                  <AddTweet
                                    nowData={[nowData]}
                                    profile={prop.userProfile}
                                  />
                                </div>
                              </Modal>
                            )
                          )}
                        </div>
                      </div>

 

 

 

saveTweet API 사용

 

saveTweet API코드에 reply_retweet_id 데이터를 추가해서 데이터베이스에 저장

await Tweets.create({
        user_id: result.user_id,
        email: req.email,
        content: req.body.content,
        tag: req.body.tag,
        write_date: sequelize.development.literal(`now()`),
        reply_tweet_id: req.body.reply_tweet_id,

 

 

 

 

참고 사이트


React 기초) useState 배열 상태 값 변경하는 방법(spread 문법)

리액트 불변성이란 무엇이고, 왜 지켜야 할까?

React 모달 밖 영역 클릭시 닫기