๐Ÿ“ ํšŒ์›๊ฐ€์ž…์‹œ ๋‹‰๋„ค์ž„ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

Doozuuยท2023๋…„ 7์›” 22์ผ
1

React

๋ชฉ๋ก ๋ณด๊ธฐ
21/23
post-custom-banner

์š”๊ตฌ์‚ฌํ•ญ

ํšŒ์›๊ฐ€์ž…์‹œ์— ์•„๋ž˜์™€ ๊ฐ™์ด ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค.

์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํ•ญ๋ชฉ

  1. ๋‹‰๋„ค์ž„ ๊ธธ์ด๊ฐ€ 2 ์ด์ƒ์ด์–ด์•ผ ํ•œ๋‹ค.
  2. ๊ธฐ์กด ๋‹‰๋„ค์ž„๊ณผ ์ค‘๋ณต๋˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.

์ถ”๊ฐ€์ ์ธ ์š”๊ตฌ์‚ฌํ•ญ

  • ์ž…๋ ฅ์ฐฝ์ด focus ๋˜์–ด ์žˆ์„ ๋•Œ์—๋งŒ ๊ฒฝ๊ณ ์ฐฝ์ด ๋œจ๋„๋ก ํ•œ๋‹ค.
  • ์•„๋ฌด๊ฒƒ๋„ ์ž…๋ ฅํ•˜์ง€ ์•Š๊ณ  ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ๋Š” ์ž…๋ ฅ์ฐฝ์ด focus๋˜๊ณ , 2๊ธ€์ž ์ด์ƒ ์ž…๋ ฅํ•˜๋ผ๋Š” ๊ฒฝ๊ณ ์ฐฝ์ด ๋œจ๋„๋ก ํ•œ๋‹ค.
  • ๊ธฐ์กด ๋‹‰๋„ค์ž„๊ณผ ์ค‘๋ณต๋  ๋•Œ๋Š” ์ž…๋ ฅ์ฐฝ์ด focus๋˜๊ณ , ๋‹‰๋„ค์ž„์ด ์ค‘๋ณต๋œ๋‹ค๋Š” ๊ฒฝ๊ณ ์ฐฝ์ด ๋œจ๋„๋ก ํ•œ๋‹ค.
  • ์ด๋•Œ, ์ž…๋ ฅ ๋‚ด์šฉ์„ ๋ฐ”๊พธ๋ฉด ์ค‘๋ณต๋œ๋‹ค๋Š” ๊ฒฝ๊ณ ์ฐฝ์ด ์‚ฌ๋ผ์ง€๋„๋ก ํ•œ๋‹ค.



์š”๊ตฌ์‚ฌํ•ญ ํ•ด๊ฒฐ๋ฐฉ์‹

1. ๋‹‰๋„ค์ž„ ๊ธธ์ด๊ฐ€ 2 ์ด์ƒ์ด์–ด์•ผ ํ•œ๋‹ค.

๐Ÿ‘‰๐Ÿป ์ž…๋ ฅ์ฐฝ์— ์ž…๋ ฅ๋˜๋Š” ๋‚ด์šฉ์„ state์— ์ €์žฅํ•ด ๊ธธ์ด๊ฐ€ 2 ์ด์ƒ์ธ์ง€ ์ฒดํฌํ•œ๋‹ค.


2. ๊ธฐ์กด ๋‹‰๋„ค์ž„๊ณผ ์ค‘๋ณต๋˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.

๐Ÿ‘‰๐Ÿป ์ž…๋ ฅ๋œ ๋‹‰๋„ค์ž„์„ ๋ฐฑ์—”๋“œ๋กœ ๋ณด๋‚ด ์ค‘๋ณต ์—ฌ๋ถ€๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.


3. ์ž…๋ ฅ์ฐฝ์ด focus ๋˜์–ด ์žˆ์„ ๋•Œ์—๋งŒ ๊ฒฝ๊ณ ์ฐฝ์ด ๋œจ๋„๋ก ํ•œ๋‹ค.

๐Ÿ‘‰๐Ÿป useRef๋ฅผ ์ด์šฉํ•ด ์ž…๋ ฅ์ฐฝ์˜ focus ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ , ์ด๋ฅผ state์— ์ €์žฅํ•œ๋‹ค. ์ด state ๊ฐ’์ด true์ผ ๋•Œ๋งŒ ๊ฒฝ๊ณ ์ฐฝ์ด ๋œจ๋„๋ก ์„ค์ •ํ•œ๋‹ค.


4. ์ž…๋ ฅํ•œ ๋‚ด์šฉ์˜ ๊ธธ์ด๊ฐ€ 2๋ณด๋‹ค ์ž‘์€๋ฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ๋Š” ์ž…๋ ฅ์ฐฝ์ด focus๋˜๊ณ , 2๊ธ€์ž ์ด์ƒ ์ž…๋ ฅํ•˜๋ผ๋Š” ๊ฒฝ๊ณ ์ฐฝ์ด ๋œจ๋„๋ก ํ•œ๋‹ค.

๐Ÿ‘‰๐Ÿป ๋‹‰๋„ค์ž„ ๊ธธ์ด๊ฐ€ 2๋ณด๋‹ค ์ž‘์„ ๋•Œ focus๋ฅผ true๋กœ ๋ฐ”๊พผ๋‹ค.


5. ๊ธฐ์กด ๋‹‰๋„ค์ž„๊ณผ ์ค‘๋ณต๋  ๋•Œ๋Š” ์ž…๋ ฅ์ฐฝ์ด focus๋˜๊ณ , ๋‹‰๋„ค์ž„์ด ์ค‘๋ณต๋œ๋‹ค๋Š” ๊ฒฝ๊ณ ์ฐฝ์ด ๋œจ๋„๋ก ํ•œ๋‹ค.

๐Ÿ‘‰๐Ÿป ๋ฐฑ์—”๋“œ์—์„œ ์ค‘๋ณต๋๋‹ค๋Š” ์‘๋‹ต(400)์„ ๋ฐ›์œผ๋ฉด focus์™€ isOverlap์„ true๋กœ ๋ฐ”๊พผ๋‹ค. ์ด๋•Œ ์ž…๋ ฅํ•œ ๊ฐ’์„ temp์— ์ €์žฅํ•ด๋‘”๋‹ค.


6. ์ด๋•Œ, ์ž…๋ ฅ ๋‚ด์šฉ์„ ๋ฐ”๊พธ๋ฉด ์ค‘๋ณต๋œ๋‹ค๋Š” ๊ฒฝ๊ณ ์ฐฝ์ด ์‚ฌ๋ผ์ง€๋„๋ก ํ•œ๋‹ค.

๐Ÿ‘‰๐Ÿป ํ˜„์žฌ ์ž…๋ ฅ์ค‘์ธ ๊ฐ’๊ณผ temp๋ฅผ ๋น„๊ตํ•ด์„œ ๊ฐ™์œผ๋ฉด(์—ฌ์ „ํžˆ ์ค‘๋ณต๋˜๋Š” ์ƒํƒœ) ๊ฒฝ๊ณ ์ฐฝ์„ ๊ณ„์† ๋„์šฐ๊ณ , ๊ฐ™์ง€ ์•Š์œผ๋ฉด ๊ฒฝ๊ณ ์ฐฝ์ด ๋‚˜์˜ค์ง€ ์•Š๊ฒŒ ํ•œ๋‹ค.



๊ตฌํ˜„ ์ฝ”๋“œ

const Nickname = () => {
  const [nickname, setNickName] = useState(""); // ๋‹‰๋„ค์ž„ ์ž…๋ ฅ๋ฐ›๊ธฐ
  const [isOverlap, setIsOverlap] = useState(false); // ๋‹‰๋„ค์ž„ ์ค‘๋ณต ์ฒดํฌ
  const [isFocused, setIsFocused] = useState(false); // focus ์—ฌ๋ถ€
  const [temp, setTemp] = useState(""); // ํ˜„์žฌ ์ž…๋ ฅ๊ฐ’์ด ์ค‘๋ณต๋˜๋Š”์ง€ ์ฒดํฌ
  const inputRef = useRef(null); // focus ๊ฐ์ง€
  const navigate = useNavigate();

  const handleNavigateBack = () => {
    navigate(-1);
  };

  const handleNickName = e => {
    setNickName(e.target.value);
  };

  // focus ์—ฌ๋ถ€ ๊ฐ์ง€
  useEffect(() => {
    const inputElement = inputRef.current;
    inputElement.addEventListener("focus", () => setIsFocused(true));
    inputElement.addEventListener("blur", () => setIsFocused(false));

    return () => {
      inputElement.removeEventListener("focus", () => setIsFocused(true));
      inputElement.removeEventListener("blur", () => setIsFocused(false));
    };
  }, []);

  const putNickName = async () => {
    if (nickname.length < 2) {
      setIsFocused(true);
    } else {
      const token = localStorage.getItem("bagtoken");

      try {
        const res = await axios.put(
          "https://server.bageasy.net/members/nickname",
          {
            nickname: nickname,
          },
          {
            headers: {
              Authorization: token,
            },
          },
        );
        console.log(res);
        if (res.status == "400") {
          setIsOverlap(true);
          setIsFocused(true);
          setTemp(nickname);
        }
        if (res.status == "200") {
          setIsOverlap(false);
          setIsFocused(false);
          setTemp("");
          navigate("/home");
        }
      } catch (error) {
        console.log(error);
      }
    }
  };

  return (
    <NickNameContainer>
      <ArrowIcon src={Arrow} onClick={handleNavigateBack} />
      <Copy>๋‹‰๋„ค์ž„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”!</Copy>
      <Copy2>์ดํ›„ ๋‹‰๋„ค์ž„ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€ํ•˜๋‹ˆ ์‹ ์ค‘ํ•˜๊ฒŒ ๊ฒฐ์ •ํ•ด์ฃผ์„ธ์š”.</Copy2>
      <Container>
        <Input
          placeholder="์—ฌ๊ธฐ์— ์ž…๋ ฅํ•˜์„ธ์š”..."
          onChange={handleNickName}
          ref={inputRef}
          color={
            isFocused &&
            (nickname.length < 2 || (isOverlap && nickname === temp))
              ? "T"
              : "F"
          }
        />
        {isFocused && nickname.length < 2 && (
          <Copy3>- ๋‹‰๋„ค์ž„์„ 2๊ธ€์ž ์ด์ƒ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.</Copy3>
        )}
        {isFocused && isOverlap && nickname === temp && (
          <Copy3>- ์ค‘๋ณต๋˜๋Š” ๋‹‰๋„ค์ž„์ž…๋‹ˆ๋‹ค.</Copy3>
        )}
      </Container>
      <Btn onClick={putNickName}>ํ™•์ธ</Btn>
    </NickNameContainer>
  );
};
profile
๋ชจ๋“ ๊ฒŒ ์ƒˆ๋กญ๊ณ  ์žฌ๋ฐŒ๋Š” ํ”„๋ก ํŠธ์—”๋“œ ์ƒˆ์‹น
post-custom-banner

1๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2023๋…„ 7์›” 22์ผ

์ž˜ ๋ดค์Šต๋‹ˆ๋‹ค. ์ข‹์€ ๊ธ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ