๐Ÿ’ป ์ฝ”๋”ฉ ์ผ๊ธฐ : [์Šคํ”„๋ง ๊ฒŒ์‹œํŒ with React] 'ํšŒ์›์ •๋ณด ์ˆ˜์ •(Update)' ํŽธ

ybkยท2024๋…„ 5์›” 23์ผ

spring

๋ชฉ๋ก ๋ณด๊ธฐ
38/55
post-thumbnail

๐Ÿ””'ํšŒ์›์ •๋ณด ์ˆ˜์ •(Update)'์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž!


๐Ÿ’Ÿ ํšŒ์›์ •๋ณด ์ˆ˜์ •(Update)


Member.jsx(React)

export function MemberEdit() {
  const [member, setMember] = useState(null);
  const [passwordCheck, setPasswordCheck] = useState("");
  const [oldPassword, setOldPassword] = useState(""); //๊ธฐ์กด ํŒจ์Šค์›Œ๋“œ
  const [oldNickName, setOldNickName] = useState(""); // ๊ธฐ์กด ๋‹‰๋„ค์ž„
  const [isCheckedNickName, setIsCheckedNickName] = useState(true);
  const { id } = useParams();
  const toast = useToast();
  const navigate = useNavigate();
  const { isOpen, onClose, onOpen } = useDisclosure();

  useEffect(() => {
    axios
      .get(`/api/member/${id}`)
      .then((response) => {
        const member1 = response.data;
        setMember({ ...member1, password: "" });
        setOldNickName(member1.nickName);
      })
      .catch((err) => {
        toast({
          status: "error",
          description: "ํ•ด๋‹น ํšŒ์›์ด ์—†์Šต๋‹ˆ๋‹ค.",
          position: "top-right",
          duration: 1000,
        });
        navigate("/");
      });
  }, []);

  function handleClickSave() {
    axios
      .put(`/api/member/modify`, { ...member, oldPassword })
      .then(() => {
        toast({
          status: "success",
          description: `${member.id}๋ฒˆ ํšŒ์›์ด ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.`,
          position: "top-right",
        });
        navigate(`/member/${member.id}`);
      })
      .catch((err) => {
        if (err.response.status === 400) {
          toast({
            status: "error",
            description: `ํšŒ์› ์ •๋ณด๊ฐ€ ์ˆ˜์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ž‘์„ฑํ•œ ๋‚ด์šฉ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”.`,
            position: "top-right",
          });
        }
      })
      .finally(() => {
        onClose();
        setOldPassword("");
      });
  }

  function handleCheckNickName() {
    axios
      .get(`/api/member/check?nickName=${member.nickName}`)
      .then((res) => {
        toast({
          status: "warning",
          description: "์ค‘๋ณต๋œ ๋‹‰๋„ค์ž„์ž…๋‹ˆ๋‹ค.",
          position: "top",
          duration: 1000,
        });
      })
      .catch((err) => {
        if (err.response.status === 404) {
          toast({
            status: "info",
            description: "์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹‰๋„ค์ž„์ž…๋‹ˆ๋‹ค.",
            position: "top",
            duration: 1000,
          });
          setIsCheckedNickName(true); // ์ค‘๋ณตํ™•์ธํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉด true, ์ž…๋ ฅ์„ ์‹œ์ž‘ํ•˜๋ฉด false
        }
      })
      .finally();
  }

  if (member == null) {
    return <Spinner />;
  }

  let isDisableNickNameCheckButton = false;
  if (member.nickName === oldNickName) {
    isDisableNickNameCheckButton = true;
  }
  if (member.nickName.trim().length === 0) {
    isDisableNickNameCheckButton = true;
  }

  if (isCheckedNickName) {
    isDisableNickNameCheckButton = true;
  }

  let isDisableSaveButton = false;

  if (member.password !== passwordCheck) {
    isDisableSaveButton = true;
  }

  if (member.nickName.trim().length === 0) {
    isDisableSaveButton = true;
  }

  if (!isCheckedNickName) {
    isDisableSaveButton = true;
  }

  return (
    <Box>
      <Box>{member.id}๋ฒˆ ํšŒ์›</Box>
      <Box>
        <FormControl>
          <FormLabel>์ด๋ฉ”์ผ</FormLabel>
          <Input value={member.email} readOnly />
        </FormControl>
      </Box>
      <Box>
        <FormControl>
          <FormLabel>๋น„๋ฐ€๋ฒˆํ˜ธ</FormLabel>
          <Input
            defaultValue={member.password}
            placeholder={"์•”ํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ์ž…๋ ฅํ•˜์„ธ์š”."}
            onChange={(e) => setMember({ ...member, password: e.target.value })}
          />
          <FormHelperText color={"red"}>
            ์ž…๋ ฅํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ์กด ์•”ํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
          </FormHelperText>
        </FormControl>
      </Box>
      <Box>
        <FormControl>
          <FormLabel>๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ</FormLabel>
          <Input onChange={(e) => setPasswordCheck(e.target.value)} />
          {member.password === passwordCheck || (
            <FormHelperText color={"red"}>
              ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์ง€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
            </FormHelperText>
          )}
        </FormControl>
      </Box>
      <Box>
        <FormControl>
          <FormLabel>๋‹‰๋„ค์ž„</FormLabel>
          <InputGroup>
            <Input
              onChange={(e) => {
                const newNickName = e.target.value.trim();
                setMember({ ...member, nickName: newNickName });
                setIsCheckedNickName(newNickName === oldNickName); // ๊ธฐ์กด ๋‹‰๋„ค์ž„๊ณผ ์ƒˆ๋กœ์šด ๋‹‰๋„ค์ž„์ด ๊ฐ™์ง€ ์•Š์„๋•Œ,์ž…๋ ฅ์„ ์‹œ์ž‘ํ•  ๋•Œ ํ™œ์„ฑํ™”
              }}
              value={member.nickName}
            />
            <InputRightElement w={"100px"} mr={1}>
              <Button
                isDisabled={isDisableNickNameCheckButton}
                onClick={handleCheckNickName}
                colorScheme={"green"}
              >
                ์ค‘๋ณต ํ™•์ธ
              </Button>
            </InputRightElement>
          </InputGroup>
          {isDisableNickNameCheckButton || (
            <FormHelperText color={"red"}>
              ๋‹‰๋„ค์ž„ ์ค‘๋ณต ํ™•์ธ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
            </FormHelperText>
          )}
        </FormControl>
      </Box>
      <Box>
        <Button
          isDisabled={isDisableSaveButton}
          colorScheme={"blue"}
          onClick={onOpen}
        >
          ์ €์žฅ
        </Button>
        <Modal isOpen={isOpen} onClose={onClose}>
          <ModalOverlay />
          <ModalContent>
            <ModalHeader>
              <FontAwesomeIcon icon={faTriangleExclamation} />
              ๊ธฐ์กด ํŒจ์Šค์›Œ๋“œ ํ™•์ธ
            </ModalHeader>
            <ModalBody>
              <FormControl>
                <FormLabel>๊ธฐ์กด ํŒจ์Šค์›Œ๋“œ</FormLabel>
                <Input onChange={(e) => setOldPassword(e.target.value)} />
              </FormControl>
            </ModalBody>
            <ModalFooter>
              <Button onClick={handleClickSave} colorScheme={"blue"}>
                ํ™•์ธ
              </Button>
              <Button onClick={onClose}>์ทจ์†Œ</Button>
            </ModalFooter>
          </ModalContent>
        </Modal>
      </Box>
    </Box>
  );
}
  • ์ˆ˜์ • ํŽ˜์ด์ง€์—์„œ ์ด๋ฉ”์ผ, ๋น„๋ฐ€๋ฒˆํ˜ธ, ๋‹‰๋„ค์ž„, ๊ฐ€์ž…์ผ์‹œ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ /api/member/${id} ๊ฒฝ๋กœ๋กœ GET ์š”์ฒญ์„ ํ•ด์„œ member ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์˜ค๋Š”๋ฐ ๊ทธ ๋•Œ member ๊ฐ์ฒด์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋นˆ ๊ฐ’์œผ๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ํ™”๋ฉด์— ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด <Input/> ํƒœ๊ทธ์—์„œ defaultValue์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ ์ €์žฅ๋˜์–ด ์žˆ๋˜ ๊ฐ’(์ดˆ๊ธฐ๊ฐ’)์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.
  • ์ €์žฅ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด /api/member/modify ๊ฒฝ๋กœ๋กœ PUT ์š”์ฒญ์„ ํ•ด์„œ member ๊ฐ์ฒด๋ฅผ ์š”์ฒญ ๋ณธ๋ฌธ์— ๋‹ด์•„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

MemberController.java

@PutMapping("modify")
public ResponseEntity modify(@RequestBody Member member) {
    if (service.hasAccessModify(member)) {
        service.modify(member);
        return ResponseEntity.ok().build();
    } else {
        return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
    }
}
  • PUT ์š”์ฒญ์„ ๋ฐ›์•„ ์š”์ฒญ ๋ณธ๋ฌธ์—์„œ ๋ฐ›์€ member ๊ฐ์ฒด๋ฅผ ์„œ๋น„์Šค์—์„œ ์ˆ˜์ • ๊ถŒํ•œ์ด ์žˆ๋‹ค๋ฉด Update ํ•  ์ˆ˜ ์žˆ๋„๋ก ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜์ • ์ž‘์—…์ด ์„ฑ๊ณตํ•˜๋ฉด ok ์‘๋‹ต์„ ํ•˜๊ณ  ์‹คํŒจํ•˜๋ฉด 403(FORBIDDEN) ์‘๋‹ต์„ ํ•ฉ๋‹ˆ๋‹ค.

MemberService.java

public void modify(Member member) {
    if (member.getPassword() != null && member.getPassword().trim().length() > 0) {
        // ํŒจ์Šค์›Œ๋“œ๊ฐ€ ์ž…๋ ฅ(๋ณ€๊ฒฝ)๋˜์—ˆ์œผ๋‹ˆ ๋ฐ”๊พธ๊ธฐ
        member.setPassword(passwordEncoder.encode(member.getPassword()));
    } else {
        // ํŒจ์Šค์›Œ๋“œ๊ฐ€ ์ž…๋ ฅ์ด ์•ˆ๋์œผ๋ฉด ๊ธฐ์กด ๊ฐ’์œผ๋กœ ์œ ์ง€
        Member dbMember = mapper.selectById(member.getId());
        member.setPassword(dbMember.getPassword());
    }
    mapper.update(member);
}

public boolean hasAccessModify(Member member) {
    Member dbMember = mapper.selectById(member.getId());
    if (dbMember == null) {
        return false;
    }

    if (!passwordEncoder.matches(member.getOldPassword(), dbMember.getPassword())) {
        return false;
    }

    return true;
}
  • modify : ํŒจ์Šค์›Œ๋“œ๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋นˆ ๊ฐ’์œผ๋กœ ๋ณด๋‚ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ํŒจ์Šค์›Œ๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์œผ๋ฉด mapper์—์„œ Update๋ฅผ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํŒจ์Šค์›Œ๋“œ๋ฅผ ์ž…๋ ฅํ–ˆ๋‹ค๋ฉด encoding ํ•ด์„œ ๋„ฃ์–ด์ฃผ๊ณ  ํŒจ์Šค์›Œ๋“œ๊ฐ€ ์ž…๋ ฅ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๊ธฐ์กด์— ์ €์žฅ๋˜์–ด ์žˆ๋˜(DB) ํšŒ์›์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์œ ์ง€ํ•ด์ค๋‹ˆ๋‹ค.
  • hasAccessModify() : ๋ฉ”ํผ์—์„œ DB์— ํšŒ์› ID๋ฅผ ์กฐํšŒํ•ด์„œ ๊ทธ ์•„์ด๋””์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ(dbMember.getPassword())์™€ ๊ธฐ์กด ๋น„๋ฐ€๋ฒˆํ˜ธ(member.getOldPassword())๊ฐ€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ  encoding์„ ํ•ด์ค๋‹ˆ๋‹ค.

MemberMapper.java

@Update("UPDATE member SET password=#{password}, nick_name=#{nickName} WHERE id=#{id}")
int update(Member member);
  • ํŒจ์Šค์›Œ๋“œ์™€ ๋‹‰๋„ค์ž„์ด ๋ฐ”๋€Œ๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ’Ÿ ์ˆ˜์ •๊ณผ ๊ด€๋ จ๋œ ๋ถ€๊ฐ€๊ธฐ๋Šฅ

1. ๋ณ„๋ช… ์ค‘๋ณต ํ™•์ธ

<Box>
  <FormControl>
    <FormLabel>๋‹‰๋„ค์ž„</FormLabel>
    <InputGroup>
      <Input
        onChange={(e) => {
          const newNickName = e.target.value.trim();
          setMember({ ...member, nickName: newNickName });
          setIsCheckedNickName(newNickName === oldNickName); // ๊ธฐ์กด ๋‹‰๋„ค์ž„๊ณผ ์ƒˆ๋กœ์šด ๋‹‰๋„ค์ž„์ด ๊ฐ™์ง€ ์•Š์„๋•Œ,์ž…๋ ฅ์„ ์‹œ์ž‘ํ•  ๋•Œ ํ™œ์„ฑํ™”
        }}
        value={member.nickName}
      />
      <InputRightElement w={"100px"} mr={1}>
        <Button
          isDisabled={isDisableNickNameCheckButton}
          onClick={handleCheckNickName}
          colorScheme={"green"}
        >
          ์ค‘๋ณต ํ™•์ธ
        </Button>
      </InputRightElement>
    </InputGroup>
    {isDisableNickNameCheckButton || (
      <FormHelperText color={"red"}>
        ๋‹‰๋„ค์ž„ ์ค‘๋ณต ํ™•์ธ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      </FormHelperText>
    )}
  </FormControl>
</Box>
  • ๋‹‰๋„ค์ž„์„ ์ž…๋ ฅํ•  ๋•Œ DB์— ์žˆ๋˜ ๋‹‰๋„ค์ž„๊ณผ ์ƒˆ๋กญ๊ฒŒ ์ž‘์„ฑํ•œ ๋‹‰๋„ค์ž„์ด ๊ฐ™์€์ง€ ๋น„๊ตํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ์šด ๋‹‰๋„ค์ž„ ๋ณ€์ˆ˜(newNickName)์„ ์ •์˜ํ•˜๊ณ  GET ์š”์ฒญ์„ ํ•ด์„œ ๋ฐ›์•„์˜จ DB์— ์žˆ๋Š” ๋‹‰๋„ค์ž„(oldNickName)์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

2. ์ค‘๋ณต ํ™•์ธ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” ์œ ๋ฌด

const [isCheckedNickName, setIsCheckedNickName] = useState(true);

let isDisableNickNameCheckButton = false; // ํ™œ์„ฑํ™” 

// ์ƒˆ๋กœ์šด ๋‹‰๋„ค์ž„๊ณผ ๊ธฐ์กด ๋‹‰๋„ค์ž„์ด ๊ฐ™๋‹ค๋ฉด ์ค‘๋ณต ํ™•์ธ ๋ฒ„ํŠผ ๋น„ํ™œ์„ฑํ™”
 if (member.nickName === oldNickName) {
   isDisableNickNameCheckButton = true;
 }

// ์ƒˆ๋กœ์šด ๋‹‰๋„ค์ž„์„ ์ž‘์„ฑํ•˜์ง€ ์•Š์œผ๋ฉด ์ค‘๋ณต ํ™•์ธ ๋ฒ„ํŠผ ๋น„ํ™œ์„ฑํ™”
if (member.nickName.trim().length === 0) {
   isDisableNickNameCheckButton = true;
 }

// ๋‹‰๋„ค์ž„ ์ค‘๋ณตํ™•์ธ ํ–ˆ์œผ๋ฉด ์ค‘๋ณต ํ™•์ธ ๋ฒ„ํŠผ ๋น„ํ™œ์„ฑํ™”
 if (isCheckedNickName) {
   isDisableNickNameCheckButton = true;
 }

3. ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ์ด ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธ

const [passwordCheck, setPasswordCheck] = useState("");

<Box>
  <FormControl>
    <FormLabel>๋น„๋ฐ€๋ฒˆํ˜ธ</FormLabel>
    <Input
      defaultValue={member.password}
      placeholder={"์•”ํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ์ž…๋ ฅํ•˜์„ธ์š”."}
      onChange={(e) => setMember({ ...member, password: e.target.value })}
    />
    <FormHelperText color={"red"}>
      ์ž…๋ ฅํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ์กด ์•”ํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    </FormHelperText>
  </FormControl>
</Box>
<Box>
  <FormControl>
    <FormLabel>๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ</FormLabel>
    <Input onChange={(e) => setPasswordCheck(e.target.value)} />
    {member.password === passwordCheck || (
      <FormHelperText color={"red"}>
        ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
      </FormHelperText>
    )}
  </FormControl>
</Box>
  • ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๊ฐ™์€์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ ๊ฐ’์„ member์˜ password์˜ ๊ฐ’์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•œ ๊ฐ’์ด๋ž‘ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ์—์„œ ์ž…๋ ฅ ํ•œ ๊ฐ’์ด๋ž‘ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.
  • ๋งŒ์•ฝ์— ์ผ์น˜ํ•˜์ง€ ์•Š๋‹ค๋ฉด ๋ฉ”์„ธ์ง€๊ฐ€ ๋‚˜์˜ค๊ณ  ์ผ์น˜ํ•˜๋‹ค๋ฉด ๋ฉ”์„ธ์ง€๊ฐ€ ์ง€์›Œ์ง‘๋‹ˆ๋‹ค.

4. ์ €์žฅ ๋ฒ„ํŠผ ๋น„ํ™œ์„ฑํ™”(isDisabled)

let isDisableSaveButton = false; //ํ™œ์„ฑํ™”

// ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๊ฐ™์ง€ ์•Š์œผ๋ฉด ์ €์žฅ ๋ฒ„ํŠผ ๋น„ํ™œ์„ฑํ™”
if (member.password !== passwordCheck) {
  isDisableSaveButton = true; 
}

// ์ž‘์„ฑํ•œ ๋‹‰๋„ค์ž„์ด ์—†๋‹ค๋ฉด ์ €์žฅ ๋ฒ„ํŠผ ๋น„ํ™œ์„ฑํ™”
if (member.nickName.trim().length === 0) {
  isDisableSaveButton = true;
}

// ๋‹‰๋„ค์ž„ ์ค‘๋ณต์„ ํ™•์ธํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๋น„ํ™œ์„ฑํ™”
if (!isCheckedNickName) {
  isDisableSaveButton = true;
}

5. ์ €์žฅ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๋ชจ๋‹ฌ ํ™•์ธ(๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ)

<Modal isOpen={isOpen} onClose={onClose}>
  <ModalOverlay />
  <ModalContent>
    <ModalHeader>
      <FontAwesomeIcon icon={faTriangleExclamation} />
      ๊ธฐ์กด ํŒจ์Šค์›Œ๋“œ ํ™•์ธ
    </ModalHeader>
    <ModalBody>
      <FormControl>
        <FormLabel>๊ธฐ์กด ํŒจ์Šค์›Œ๋“œ</FormLabel>
        <Input onChange={(e) => setOldPassword(e.target.value)} />
      </FormControl>
    </ModalBody>
    <ModalFooter>
      <Button onClick={handleClickSave} colorScheme={"blue"}>
        ํ™•์ธ
      </Button>
      <Button onClick={onClose}>์ทจ์†Œ</Button>
    </ModalFooter>
  </ModalContent>
</Modal>
  • ์ €์žฅ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด Modal์ด ๋‚˜ํƒ€๋‚˜๊ณ  Modal์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์•ผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • PUT ์š”์ฒญํ•  ๋•Œ, ์š”์ฒญ ๋ณธ๋ฌธ์— member ๊ฐ์ฒด์˜ ๋ชจ๋“  ์†์„ฑ์„ ๋ณต์‚ฌํ•˜๊ณ  ์—ฌ๊ธฐ์— oldPassword ์†์„ฑ์„ ๋ง๋ถ™์ธ ํ˜•ํƒœ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ธฐ์กด ํŒจ์Šค์›Œ๋“œ๋ฅผ ์ž…๋ ฅํ•ด์„œ ๊ฐ™๋‹ค๋ฉด ์ˆ˜์ •์ด ๋˜๊ณ  ๊ฐ™์ง€ ์•Š์œผ๋ฉด ์ˆ˜์ •์ด ์•ˆ๋ฉ๋‹ˆ๋‹ค.
profile
๊ฐœ๋ฐœ์ž ์ค€๋น„์ƒ~

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