[Main_day18]2022.12.01 회고_ 태그박스 구현 방법 수정, 값 넘겨주기

wool·2022년 12월 11일
0

회고

목록 보기
26/29

Intro


기상 시간오전..?
전날 취침 시간왜 오전,,,?
컨디션이상하게좋다!
  • 이제 기상과 취침시간을 적는 것이 의미가 없어졌다^^

1201 회고 이슈


잘해오고 있는 부분

<개인>

  • 기능 구현에 있어 다른 팀원과 상의하면서 대량 트래픽 문제 고려하며 구현함
  • 팀원의 의견을 적극적으로 반영하려고 함

아쉬운 부분

  • 수면시간 관리가 어려운 것
  • 개발 속도가 느린 것

개선할 점

  • 잘 하고싶어서 밤을 새게 되고 그게 컨디션 악화로 이어지고 컨디션 악화는 멘탈로 이어지게 된다. 아무리 시간이 빠듯해도 최소 수면시간은 지키면서 하기로 하자

Today log


태그박스 구현 방법 수정됨!

  • 알아보기 힘들겠지만 새벽에 회의 했던 흔적을 남긴다..ㅎㅎ

  • 원래는 위와 같이 모든 사용자의 아이디를 아래와 같이 불러서 그 아이디 속에서 input창에 사용자가 입력 하면 필터링 하여 보여주는 형식으로 제작 하려고 했다. 하지만 이렇게 될 경우 1000명의 유저가 있을 경우 get요청 시 1000명의 아이디 모두 불러오기엔 비 효율적이라는 의견이 나왔고 그 의견에 나도 동의했다.
  • 바뀐 방식은 get요청 시 엔드포인트 뒤의 쿼리문에서 사용자가 input창에 입력한 값을 넣어 주고 사용자가 input창이 바뀔 때 마다 다른 엔드포인트로 get요청을 하는 것이다.
  • 당장에는 get요청이 여러 번 가능 것 같아 비 효율 적으로 보일 수 있으나, 100명의 유저보다 더 많은 유저 정보를 한꺼번에 가져 오는 것 보다 효율적이라 생각했다.
import axios from "axios";
import client from "../../client/client";

/**
 * @author yeowool
 * @description searchInput을 props로 받아서 검색 조건에 맞는 id 배열을 return
 **/

const getAllUserId = (searchInput: string) => {
  // 요청메소드 + 요청정보
  return axios.get(`/members/search?id=${searchInput}`, {
    baseURL: process.env.NEXT_PUBLIC_API_URL,
    headers: {
      withCredentials: true,
      "Content-Type": `application/json`,
    },
  });
};

export default getAllUserId;

이렇게 get요청을 보내고 뒤에 사용자가 입력하는 input을 넣는다.

  • 구현완료!

  • 완성 코드 getAllUserId.tsx
    import axios from "axios";
    import client from "../../client/client";
    
    /**
     * @author yeowool
     * @description searchInput을 props로 받아서 검색 조건에 맞는 id 배열을 return
     **/
    
    const getAllUserId = (searchInput: string) => {
      // 요청메소드 + 요청정보
      return axios.get(`/members/search?id=${searchInput}`, {
        baseURL: process.env.NEXT_PUBLIC_API_URL,
        headers: {
          withCredentials: true,
          "Content-Type": `application/json`,
        },
      });
    };
    
    export default getAllUserId;
    useGetAllUsers.tsx
    import {
      useQuery,
      useQueryClient,
      useQueryErrorResetBoundary,
    } from "react-query";
    import getUserId from "../../apis/user/getUserId";
    
    const useGetAllUsers = (searchInput: string) => {
      return useQuery(["get/useGetAllUser"], () => getUserId(searchInput), {
        enabled: false,
      });
    };
    
    export default useGetAllUsers;
    AddShareContainer.tsx
    import BoardModalContainer from "./BoardModalContainer";
    import Search from "./Search";
    import React, { useEffect, useState } from "react";
    import { useRecoilState } from "recoil";
    import { modalOpenState } from "../recoil/calendarAtom";
    import useGetAllUsers from "../hooks/user/useGetAllUsers";
    import ShareNoticeContainer from "./ShareNoticeContainer";
    
    interface idType {
      id: string;
    }
    
    interface ShareProps {
      changeShare: (share: string) => void;
    }
    
    const AddShareContainer = ({ changeShare }: ShareProps) => {
      const [open, setOpen] = useRecoilState(modalOpenState);
    
      const [input, setInput] = useState<string>("");
      const [categoryList, setCategoryList] = useState<Array<idType>>([]);
    
      const [tagList, setTagList] = useState<Array<idType>>([]);
      const [isNotEmpty, setisNotEmpty] = useState<boolean>(false);
      const [searchTag, setsearchTag] = useState<string>("");
    
      const { data: allUsers, refetch: allUsersRefetch } = useGetAllUsers(input);
    
      const Tagging = (e: any) => {
        allUsersRefetch();
    
        const userId = e.target.value;
    
        setsearchTag(userId);
    
        const newTagList = tagList;
        newTagList.push({ id: e.target.value });
        setTagList(newTagList);
    
        setInput("");
      };
    
      const deleteTagItem = (id: string) => {
        for (let i = 0; i < tagList.length; i++) {
          if (tagList[i].id === id) {
            setTagList(
              tagList.filter((element, index) => {
                return element.id !== id;
              }),
            );
          }
        }
      };
    
      useEffect(() => {
        if (allUsers !== undefined) {
          const userSearch = allUsers.data;
    
          const filterdUserTags = userSearch.filter((x: { id: string }) =>
            x.id.includes(input),
          );
    
          const filteredTagLists = filterdUserTags
            .map((el: any) => el.id)
            .filter((el: any) => !tagList.map(el => el.id).includes(el))
            .map((el: any) => ({ id: el }));
    
          setisNotEmpty(true);
          setCategoryList(filteredTagLists);
        }
    
        let sendtags: string = "";
    
        for (let i = 0; i < tagList.length; i++) {
          if (i === tagList.length - 1) {
            sendtags += tagList[i].id;
          } else {
            sendtags += tagList[i].id + ",";
          }
        }
    
        changeShare(sendtags);
      }, [allUsers]);
    
      const inputChange = async (e: any) => {
        const inputValue = e.target.value;
        if (inputValue !== "") {
          await setInput(inputValue);
          await allUsersRefetch();
        } else {
          setisNotEmpty(false);
          setInput("");
        }
      };
    
      useEffect(() => {
        if (open === false) {
          setTagList([]);
          changeShare("");
          setInput("");
        }
      }, [open]);
    
      return (
        <>
          <BoardModalContainer>
            <div className="flex flex-row w-full h-fit justify-between items-center p-0.5">
              <div className=" w-full h-fit  inline-flex relative items-start flex-rap">
                <div className="w-fit h-fit flex ">
                  <Search />
                </div>
                <div className="pl-2 w-full h-fit  flex flex-col flex-rapo ">
                  <input
                    type="text"
                    value={input}
                    placeholder="공유하고 싶은 사람을 검색하세요!"
                    className="ml-1 w-full font-SCDream3 text-left text-sm md:text-sm lg:text-sm p-1 rounded-md text-gray-700 outline-none"
                    onChange={inputChange}
                  />
    
                  <div className="w-full h-full flex items-baseline flex-row flex-wrap">
                    {tagList.map((tagItem, index) => {
                      return (
                        <div
                          key={index}
                          onClick={() => deleteTagItem(tagItem.id)}
                          className="mr-2 mb-2 text-white pr-3 pl-2 pm-2 cursor-pointer inline-flex justify-center w-fit h-full hover:bg-red-400 bg-btnOrange rounded-full"
                        >
                          <p className="pb-1">{tagItem.id}</p>
                          <button className="text-lg">
                            <svg
                              xmlns="http://www.w3.org/2000/svg"
                              fill="none"
                              viewBox="0 0 24 24"
                              stroke-width="3"
                              stroke="currentColor"
                              className="w-4 h-4"
                            >
                              <path
                                stroke-linecap="round"
                                stroke-linejoin="round"
                                d="M6 18L18 6M6 6l12 12"
                              />
                            </svg>
                          </button>
                        </div>
                      );
                    })}
                    {tagList.length !== 0 ? (
                      <p className="text-xs font-SCDream3 text-gray-700 min-w-fit">
                        님과 함께합니다
                      </p>
                    ) : null}
                  </div>
    
                  <div
                    className={`w-full ${isNotEmpty && input ? null : "hidden"}`}
                    // className={`pl-2 w-full h-fit max-h-28 flex flex-col flex-rap ${
                    //   tagList.length === 0 ? null : "overflow-x-auto "
                    // }`}
                    role="menu"
                  >
                    <div className="w-full h-full flex items-baseline flex-row flex-wrap flex-rap ">
                      {categoryList.map((el: { id: string }) => {
                        return (
                          <button
                            key={el.id}
                            className="my-1 mr-5 pb-1 text-white pr-3 pl-2 pm-3 cursor-pointer inline-flex justify-center w-fit h-full  hover:bg-btnOrange bg-underbar rounded-full "
                            onClick={Tagging}
                            value={el.id}
                          >
                            {el.id}
                          </button>
                        );
                      })}
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </BoardModalContainer>
        </>
      );
    };
    
    export default AddShareContainer;

선택된 유저들 최종 제출 컴포넌트로 넘겨주기

[React, typescript] 다른 컴포넌트에 props로 함수 넘겨주기

  • 위의 글을 참고하여 넘겨주었다
  • api로 유저를 불러와서 보여준 후 유저가 선택한 유저 배열을 최종 게시물 제출 컴포넌트로 넘겨 주어야 했다.
  • 인터페이스 지정, 태깅이 이루어지는 컴포넌트에 props로 선언 한 후에 최종 제출이 이루어지는 컴포넌트에서 컴포넌트 선언 후 인터페이스로 지정한 이름대로 값을 넣어주었다.
    • 태깅이 이루어지는 컴포넌트(AddShareContainer )
      // 인터페이스 선언
      interface ShareProps {
        changeShare: (share: string) => void;
      }
      
      // props 선언
      const AddShareContainer = ({ changeShare }: ShareProps) => {
      ...
      // 최종 선택한 태그 props에 담기
      changeShare(sendtags);
      ...
    • 태깅 된 유저를 받는 컴포넌트
      // 태깅이 이루어지는 컴포넌트 inport
      import AddShareContainer from "./AddShareContainer";
      ...
      // 태그유저값 상태선언
      const [share, setShare] = useState<any>([]);
      ...
      // props함수 선언
      const changeShare = (share: string) => {
          setShare(share);
        };
      ...
      // 태그 렌더와 함께 props조건에 맞추어 작성
      <AddShareContainer changeShare={changeShare} />

느낀점


나는 아직 기능 구현에 급급해서 어떤게 더 효율적인지 생각을 못했던 듯 하다.

다른 팀원의 말을 들으니 정말 그렇겠구나 라는 생각을 했다.

나중에 비슷한 기능을 구현 할 경우 거기에서는 100명의 유저가 아닌 더 많은 유저를 대상으로 기능을 구현 할 텐데 이렇게 기능이 어떻게 하면 효율적으로 구현 될 수 있을까에 대한 고민의 중요성을 깨닫게 된 날이었다.

profile
毎日一つづつゆっくり

0개의 댓글