๐ŸŒŸ CRUD: Delete and Update

summereuna๐Ÿฅยท2022๋…„ 4์›” 11์ผ

๐ŸŒŸ Twinkle (React, Firebase)

๋ชฉ๋ก ๋ณด๊ธฐ
16/42

๋ˆ„๊ตฐ๊ฐ€ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์ง€์šด ๋Œ“๊ธ€์ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋‚˜ํƒ€๋‚˜๋Š”๊ฑด ๋ณด๊ณ  ์‹ถ์ง€ ์•Š๋‹ค.
๋ชจ๋“  ํŽ˜์ด์ง€๋‚˜ ์š”์†Œ๊ฐ€ ์‹ค์‹œ๊ฐ„์ผ ํ•„์š”๋Š” ์—†๋‹ค.

ํŠธ์œ—์„ ์ˆ˜์ •ํ•˜๊ณ  ์ง€์šฐ๋Š” ๊ธฐ๋Šฅ์„ ๋„ฃ์–ด ๋ณด์ž.



โœ… ๋จผ์ € Tweet ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค๊ธฐ


๐Ÿ“ /components/Tweet.js

์•ž์œผ๋กœ ํŠธ์œ—์— ๋“ค์–ด๊ฐ€๋Š” ๋‚ด์šฉ์ด ๋งŽ์•„์งˆ ์˜ˆ์ •์ด๋‹ˆ ํŠธ์œ— ์ž์ฒด๋ฅผ ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๋“ค์–ด ๋ฒ„๋ฆฌ์ž.

  1. tweetObj ์˜ค๋ธŒ์ ํŠธ๋ฅผ props์œผ๋กœ ๋ฐ›์•„ tweetObj ์˜ค๋ธŒ์ ํŠธ์˜ text๋ฅผ h4๋กœ ๋ Œ๋”ํ•œ๋‹ค.
  2. export default๋กœ ๋‚ด๋ณด๋‚ธ๋‹ค.
import React from "react";

const Tweet = ({ tweetObj }) => (
  <div>
    <h4>{tweetObj.text}</h4>
  </div>
);

export default Tweet;

๐Ÿ“ /routes/Home.js

ํŠธ์œ—์— ๋ Œ๋”๋˜๋Š” Home ํŽ˜์ด์ง€์— Tweet ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•˜์ž.

  1. import๋กœ Tweet ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
  2. ํŠธ์œ— ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋“ค์–ด๊ฐˆ ์œ„์น˜์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
    ๊ธฐ์กด์— ์ž‘์„ฑํ•œ map() ํ™œ์šฉํ•˜์—ฌ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.
    • ์ด ๋•Œ, tweetObj ํ”„๋กญ์— tweets ์–ด๋ ˆ์ด์—์„œ ๋ฐ›์•„์˜จ ๊ฐ๊ฐ์˜ tweet์„ ๋ณด๋‚ด์ค€๋‹ค.
      • ๊ทธ๋ž˜์•ผ Tweet ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด ํ”„๋กญ์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
        ๋”ฐ์ง€์ž๋ฉด ์ˆœ์„œ์ƒ ์ด๊ฒŒ ๋จผ์ €์ธ ์…ˆใ…‡ใ…‡!
//์ƒ๋žต
import Tweet from "components/Tweet";
//์ƒ๋žต
{/*DB์—์„œ ๊ฐ€์ ธ์˜จ ํŠธ์œ„ํ„ฐ ๋‚˜์—ด*/}
      <div>
        {tweets.map((tweet) => (
          //Tweet์„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๊ณ  props์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.
          //tweetObj ๋งŒ๋“ค ๋•Œ ๊ฐ๊ฐ์˜ tweet์— ํ• ๋‹นํ•œ id ๊ฐ’์„ div์˜ key์— ๋„ฃ์–ด์ฃผ์ž
          <Tweet key={tweet.id} tweetObj={tweet} />
        ))}
      </div>

โœ… ํŠธ์œ— ์‚ญ์ œ/์ˆ˜์ • ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ


1. ์‚ญ์ œ/์ˆ˜์ • ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ

import React from "react";

const Tweet = ({ tweetObj }) => (
  <div>
    <h4>{tweetObj.text}</h4>
    <button>์‚ญ์ œ</button>
    <button>์ˆ˜์ •</button>
  </div>
);

export default Tweet;

2. ํŠธ์œ— ๋ˆ„๊ฐ€ ์ž‘์„ฑํ–ˆ๋Š”์ง€ ํŒŒ์•…ํ•˜๊ธฐ

ํŠธ์œ—์„ ์ž‘์„ฑํ•œ ์‚ฌ๋žŒ๋งŒ ํ•ด๋‹นํ•˜๋Š” ํŠธ์œ—์„ ์‚ญ์ œ/์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์•ผ ํ•œ๋‹ค.
Home.js์—์„œ userObj๋ฅผ ๋ฐ›์•„์˜ค๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ˆ„๊ฐ€ ์ž‘์„ฑํ•œ ํŠธ์œ—์ธ์ง€ ํŒŒ์•…ํ•˜๊ณ  ๊ทธ์— ๋”ฐ๋ผ ์‚ญ์ œ/์ˆ˜์ • ๋ฒ„ํŠผ์ด ๋ณด์ด๊ฒŒ ํ•˜๋ฉด ๋œ๋‹ค.

๐Ÿ“ /routes/Home.js

ํ•ด๋‹นํ•˜๋Š” ํŠธ์œ—์˜ creatorId์™€ userObj์˜ uid๊ฐ€ ๊ฐ™์œผ๋ฉด true, ๋‹ค๋ฅด๋ฉด false๊ฐ€ ๋˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
isOwner={tweet.creatorId === userObj.uid}

{/*DB์—์„œ ๊ฐ€์ ธ์˜จ ํŠธ์œ„ํ„ฐ ๋‚˜์—ด*/}
<div>
  {tweets.map((tweet) => (
    //Tweet์„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๊ณ  props์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.
    //tweetObj ๋งŒ๋“ค ๋•Œ ๊ฐ๊ฐ์˜ tweet์— ํ• ๋‹นํ•œ id ๊ฐ’์„ div์˜ key์— ๋„ฃ์–ด์ฃผ์ž
    <Tweet
      key={tweet.id}
      tweetObj={tweet}
      //ํ•ด๋‹นํ•˜๋Š” ํŠธ์œ—์˜ creatorId์™€ userObj์˜ uid๊ฐ€ ๊ฐ™์œผ๋ฉด true, ๋‹ค๋ฅด๋ฉด false๊ฐ€ ๋จ
      isOwner={tweet.creatorId === userObj.uid}
      />
  ))}
</div>

๐Ÿ“ /components/Tweet.js

  1. isOwner ํ”„๋กญ ๋ฐ›์•„์˜ค๊ธฐ
  2. ํŠธ์œ— ์ฃผ์ธ์ธ ๊ฒฝ์šฐ๋งŒ ์‚ญ์ œ/์ˆ˜์ • ๋ฒ„ํŠผ ๋ณด์ด๊ฒŒํ•˜๊ธฐ
import React from "react";

//isOwner ํ”„๋กญ ๋ฐ›์•„์˜ค๊ธฐ
const Tweet = ({ tweetObj }, isOwner) => (
  <div>
    <h4>{tweetObj.text}</h4>
    {/*ํŠธ์œ— ์ฃผ์ธ์ธ ๊ฒฝ์šฐ๋งŒ ์‚ญ์ œ/์ˆ˜์ • ๋ฒ„ํŠผ ๋ณด์ด๊ฒŒ*/}
    {isOwner && (
      <>
        <button>์‚ญ์ œ</button>
        <button>์ˆ˜์ •</button>
      </>
    )}
  </div>
);

export default Tweet;

โœ… ํŠธ์œ— ์‚ญ์ œ ์ฝ”๋“œ


  1. ์‚ญ์ œ๋ฒ„ํŠผ ํด๋ฆญ์‹œ, ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ onDeleteClick ๋ฆฌ์Šค๋„ˆ๊ฐ€ ๋“ฃ๊ฒŒ ํ•˜์ž.
    <button onClick={onDeleteClick}>์‚ญ์ œ</button>

  2. onDeleteClick ๋ฆฌ์Šค๋„ˆ์—๋Š” ํŠธ์œ—์„ ์‚ญ์ œํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

    ๋‹คํ๋จผํŠธ, ์ฆ‰ ํŠธ์œ—์„ ์‚ญ์ œํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” firestore์˜ reference์ธ delete()๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

    • ์˜ˆ์‹œ

      import { doc, deleteDoc } from "firebase/firestore";
      
       await deleteDoc(doc(db, "cities", "DC"));

  3. ๋จผ์ € doc() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋””๋น„ > ํŠธ์œ—์ปฌ๋ ‰์…˜ > ํ•ด๋‹นํ•˜๋Š” id ๊ฐ€์ง„ ๋‹คํ๋จผํŠธ๋ฅผ ์ฝ• ์ฐ์–ด์˜ค์ž.
    const tweetTextRef = doc(dbService, "tweets", `${tweetObj.id}`);

  4. ๊ทธ๋Ÿฌ๊ณ  ๋‚˜์„œ deleteDoc()๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹นํ•˜๋Š” ๋‹คํ๋จผํŠธ๋ฅผ ์‚ญ์ œํ•˜๋ฉด ๋œ๋‹ค.
    await deleteDoc(tweetTextRef);


๐Ÿ“ /components/Tweet.js

import React from "react";
import { dbService } from "fbase";
import { doc, deleteDoc } from "firebase/firestore";

const Tweet = ({ tweetObj }, isOwner) => {
  //๋””๋น„ > ํŠธ์œ—์ปฌ๋ ‰์…˜ > ํ•ด๋‹นํ•˜๋Š” id ๊ฐ€์ง„ ๋‹คํ๋จผํŠธ ์ฐ์–ด์˜ค๊ธฐ
  const tweetTextRef = doc(dbService, "tweets", `${tweetObj.id}`);

  //์‚ญ์ œ
  const onDeleteClick = async () => {
    const ok = window.confirm("์ •๋ง ์ด ํŠธ์œ—์„ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?");
    //console.log(ok);  //treu/false ๋ฐ˜ํ™˜ํ•จ
    if (ok) {
      //ํ•ด๋‹นํ•˜๋Š” ํŠธ์œ— ์‚ญ์ œ
      await deleteDoc(tweetTextRef);
    } else {
      console.log("์‚ญ์ œํ•˜๋Š”๋ฐ ์‹คํŒจ!");
    }
  };

  //์ˆ˜์ •

  return (
    <div>
      <h4>{tweetObj.text}</h4>
      {/*ํŠธ์œ— ์ฃผ์ธ์ธ ๊ฒฝ์šฐ๋งŒ ์‚ญ์ œ/์ˆ˜์ • ๋ฒ„ํŠผ ๋ณด์ด๊ฒŒ*/}
      {isOwner && (
        <>
          <button onClick={onDeleteClick}>์‚ญ์ œ</button>
          <button>์ˆ˜์ •</button>
        </>
      )}
    </div>
  );
};

export default Tweet;

โœ… ํŠธ์œ— ์ˆ˜์ • ์ฝ”๋“œ


๋‹คํ๋จผํŠธ, ์ฆ‰ ํŠธ์œ—์„ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” update()๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

  • ์˜ˆ์‹œ

    import { doc, updateDoc } from "firebase/firestore";
    
     const washingtonRef = doc(db, "cities", "DC");
    
     // Set the "capital" field of the city 'DC'
     await updateDoc(washingtonRef, {
       capital: true
     });

  1. ์ˆ˜์ • ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ์ˆ˜์ •๋ชจ๋“œ ํ™”๋ฉด์— ์ถœ๋ ฅ๋  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋ณธ ๊ฐ’ false์ธ state๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ ๋‹ค.
    const [editing, setEditing] = useState(false);

  2. ์ˆ˜์ •๋ชจ๋“œ๋ฉด ํŠธ์œ— ๋‚ด์šฉ์„ ์ˆ˜์ •ํ•˜๋Š” form์ด ๋ณด์ด๊ณ , ์•„๋‹ˆ๋ฉด ๊ทธ๋ƒฅ ํŠธ์œ— ๋‚ด์šฉ์ด ๋ณด์ด๋ฉด ๋œ๋‹ค.

    {editing ? (
      <>
        <form onSubmit={onSubmit}>
          <input
            value={newTweet}
            required
            type="text"
            placeholder="์ˆ˜์ •ํ•  ๋‚ด์šฉ์„ ์ž…๋ ฅํ•˜์„ธ์š”."
            onChange={onChange}
            ></input>
          <input type="submit" value="์ˆ˜์ •" />
        </form>
        <button onClick={toggleEditing}>์ทจ์†Œ</button>
        </>
    ) : (
      <>
        <h4>{tweetObj.text}</h4>
        {/*ํŠธ์œ— ์ฃผ์ธ์ธ ๊ฒฝ์šฐ๋งŒ ์‚ญ์ œ/์ˆ˜์ • ๋ฒ„ํŠผ ๋ณด์ด๊ฒŒ*/}
        {isOwner && (
          <>
            <button onClick={onDeleteClick}>์‚ญ์ œ</button>
            <button onClick={toggleEditing}>์ˆ˜์ •</button>
            </>
        )}
  3. ์ˆ˜์ •๋ชจ๋“œ์—์„œ ์ทจ์†Œ ๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด ๋‹ค์‹œ ์›๋ž˜ ํ™”๋ฉด์œผ๋กœ ๋Œ์•„๊ฐ€๋„๋ก onClick ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค๊ณ , ํŠธ์œ— ์ˆ˜์ •ํ•˜๊ธฐ ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ์ด๋ฒคํŠธ๋ฅผ ๋ฆฌ์Šจํ•˜๋Š” toggleEditing๋ฅผ ๋‹ค์‹œ ํ•œ๋ฒˆ ํ˜ธ์ถœํ•œ๋‹ค.
    toggleEditing๋Š” setEditing์„ ํ˜„์žฌ ๊ฐ’์˜ ๋ฐ˜๋Œ€ ๊ฐ’์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๋„๋ก ์ž‘์„ฑํ•˜์—ฌ ํ† ๊ธ€์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

    //์ˆ˜์ •๋ชจ๋“œ ํ† ๊ธ€ (ํ† ๊ธ€ ๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด ํ˜„์žฌ ์ƒํƒœ(๊ธฐ๋ณธ false) ๋ฐ˜๋Œ€๋กœ ๋ฐ”๋€œ
    const toggleEditing = () => setEditing((prev) => !prev);
  4. ํŠธ์œ— ๋‚ด์šฉ์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก form์„ ์ž‘์„ฑํ•œ๋‹ค.

  5. ์ˆ˜์ •๋ชจ๋“œ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ input์— ์ž…๋ ฅํ•œ ํŠธ์œ— ๋‚ด์šฉ์„ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๋„๋ก onChange ์ด๋ฒคํŠธ๋ฅผ ๋“ฃ๋Š” onChange ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
    event.target.value๋ฅผ ๋ฐ›์•„์„œ setNewTweet(value) ๋ชจ๋””ํŒŒ์ด์–ด๋กœ ๋ณด๋‚ด์–ด state๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ฉด ๋œ๋‹ค.

    const onChange = (event) => {
      const {
        target: { value },
      } = event;
      //๐Ÿ”ฅ ์ˆ˜์ •๋ชจ๋“œ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•˜๋Š” input ๊ฐ’์„ newTweet state์— ๋„ฃ๊ธฐ
      setNewTweet(value);
    };
  6. ์ˆ˜์ •๋ชจ๋“œ input์—์„œ ์ž…๋ ฅ๋œ ํŠธ์œ— ๋‚ด์šฉ ์—…๋ฐ์ดํŠธํ•˜๋Š” state๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์ž.
    ๊ธฐ๋ณธ ๊ฐ’์€ tweetObj์˜ text, ์ฆ‰ db์— ์ €์žฅ๋œ ๋‹คํ๋จผํŠธ(ํŠธ์œ—)์˜ ๋‚ด์šฉ์ด๋‹ค.
    5๋ฒˆ์—์„œ ์—…๋ฐ์ดํŠธํ•œ ๋‚ด์šฉ์„ ๋ฐ›์•„์„œ ์ด state์— ๋„ฃ์–ด์ฃผ๋Š” ๊ฑฐ๋‹ค.

    //๐Ÿ”ฅ ์ˆ˜์ •๋ชจ๋“œ input์—์„œ ์ž…๋ ฅ๋œ ํŠธ์œ— ๋‚ด์šฉ ์—…๋ฐ์ดํŠธ
    const [newTweet, setNewTweet] = useState(tweetObj.text);
  7. ๋˜ํ•œ ์ˆ˜์ •๋ชจ๋“œ์—์„œ ์ˆ˜์ •ํ•œ ํ›„ input์„ submitํ•˜๋ฉด onSubmit ๋ฆฌ์Šค๋„ˆ๋Š” updateDoc()์œผ๋กœ ํŠธ์œ— ๋‚ด์šฉ์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.
    ๊ทธ๋Ÿฌ๊ณ  ๋‚˜์„œ setEditing() ๋ชจ๋””ํŒŒ์ด์–ด๋กœ false๋ฅผ ๋ณด๋‚ด์–ด ์ˆ˜์ •๋ชจ๋“œ๋ฅผ ์ข…๋ฃŒํ•œ๋‹ค.

    await updateDoc(tweetTextRef, { text: newTweet });
    //๐Ÿ”ฅ ์—…๋Žƒํ•˜๊ณ  ๋‚˜์„œ ์ˆ˜์ •๋ชจ๋“œ false๋กœ ๋งŒ๋“ค์–ด ์ฃผ๊ธฐ
    setEditing(false);

๐Ÿ“ /components/Tweet.js

import React, { useState } from "react";
import { dbService } from "fbase";
//๐Ÿ”ฅ updateDoc ์ž„ํฌํŠธ
import { doc, deleteDoc, updateDoc } from "firebase/firestore";

const Tweet = ({ tweetObj }, isOwner) => {
  //๐Ÿ”ฅ ์ˆ˜์ •๋ชจ๋“œ์ธ์ง€ ์•„๋‹Œ์ง€ false/true
  const [editing, setEditing] = useState(false);

  //๐Ÿ”ฅ ์ˆ˜์ •๋ชจ๋“œ input์—์„œ ์ž…๋ ฅ๋œ ํŠธ์œ— ๋‚ด์šฉ ์—…๋ฐ์ดํŠธ
  const [newTweet, setNewTweet] = useState(tweetObj.text);

  //๋””๋น„ > ํŠธ์œ—์ปฌ๋ ‰์…˜ > ํ•ด๋‹นํ•˜๋Š” id ๊ฐ€์ง„ ๋‹คํ๋จผํŠธ ์ฐ์–ด์˜ค๊ธฐ
  const tweetTextRef = doc(dbService, "tweets", `${tweetObj.id}`);

  //์‚ญ์ œ
  const onDeleteClick = async () => {
    const ok = window.confirm("์ •๋ง ์ด ํŠธ์œ—์„ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?");
    //console.log(ok);  //treu/false ๋ฐ˜ํ™˜ํ•จ
    if (ok) {
      //ํ•ด๋‹นํ•˜๋Š” ํŠธ์œ— ์‚ญ์ œ
      await deleteDoc(tweetTextRef);
    } else {
      console.log("์‚ญ์ œํ•˜๋Š”๋ฐ ์‹คํŒจ!");
    }
  };

  //๐Ÿ”ฅ ์ˆ˜์ •๋ชจ๋“œ ํ† ๊ธ€ (ํ† ๊ธ€ ๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด ํ˜„์žฌ ์ƒํƒœ(๊ธฐ๋ณธ false) ๋ฐ˜๋Œ€๋กœ ๋ฐ”๋€œ
  const toggleEditing = () => setEditing((prev) => !prev);

  //๐Ÿ”ฅ ์ˆ˜์ •๋ชจ๋“œ์—์„œ ํŠธ์œ— ์ˆ˜์ • ํ›„ ํผ ์„œ๋ฐ‹ํ•ด์„œ ํŠธ์œ— ๋‚ด์šฉ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ
  const onSubmit = async (event) => {
    event.preventDefault();
    const ok = window.confirm("์ •๋ง ์ด ํŠธ์œ—์„ ์ˆ˜์ •ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?");
    if (ok) {
      await updateDoc(tweetTextRef, { text: newTweet });
      //๐Ÿ”ฅ ์—…๋Žƒํ•˜๊ณ  ๋‚˜์„œ ์ˆ˜์ •๋ชจ๋“œ false๋กœ ๋งŒ๋“ค์–ด ์ฃผ๊ธฐ
      setEditing(false);
    }
  };

  const onChange = (event) => {
    const {
      target: { value },
    } = event;
    //๐Ÿ”ฅ ์ˆ˜์ •๋ชจ๋“œ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•˜๋Š” input ๊ฐ’์„ newTweet state์— ๋„ฃ๊ธฐ
    setNewTweet(value);
  };

  return (
    <div>
      {/*์ˆ˜์ •๋ชจ๋“œ ๋ฒ„ํŠผ ํด๋ฆญ๋œ ๊ฑฐ๋ฉด(true) ์ˆ˜์ •ํ•  ํผ ๋ณด์—ฌ์ฃผ๊ณ  : ์•„๋‹ˆ๋ฉด(false) ํŠธ์œ— ๋‚ด์šฉ ๋ณด์—ฌ์ฃผ๊ธฐ*/}
      {editing ? (
        <>
          <form onSubmit={onSubmit}>
            <input
              value={newTweet}
              required
              type="text"
              placeholder="์ˆ˜์ •ํ•  ๋‚ด์šฉ์„ ์ž…๋ ฅํ•˜์„ธ์š”."
              onChange={onChange}
            ></input>
            <input type="submit" value="์ˆ˜์ •" />
          </form>
          <button onClick={toggleEditing}>์ทจ์†Œ</button>
        </>
      ) : (
        <>
          <h4>{tweetObj.text}</h4>
          {/*ํŠธ์œ— ์ฃผ์ธ์ธ ๊ฒฝ์šฐ๋งŒ ์‚ญ์ œ/์ˆ˜์ • ๋ฒ„ํŠผ ๋ณด์ด๊ฒŒ*/}
          {isOwner && (
            <>
              <button onClick={onDeleteClick}>์‚ญ์ œ</button>
              <button onClick={toggleEditing}>์ˆ˜์ •</button>
            </>
          )}
        </>
      )}
    </div>
  );
};

export default Tweet;
profile
Always have hope๐Ÿ€ & constant passion๐Ÿ”ฅ

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