React - 시작하기 (3. UPDATE)

sarang_daddy·2023년 5월 6일
0

React

목록 보기
3/26
post-thumbnail

CREATE에 이어 UPDATE 기능을 학습해보자.
UPDATECREATE + READ를 함께 구현한다는 개념이다.

⛔️ 생활코딩 - 리액트 강의를 정리한 내용입니다.

UPDATE 페이지 만들기

let content = null;
let contextControl = null; // 1️⃣

if (mode === "WELCOME") {
    content = <Article title="Wellcome" body="Hello, React"></Article>;
  } else if (mode === "READ") { // 2️⃣
    let title, body = null;

    topics.forEach((topic) => {
      if (topic.id === id) {
        title = topic.title;
        body = topic.body;
      }
    });
    content = <Article title={title} body={body}></Article>;
    // 3️⃣
    contextControl = (
      <li>
        <a href={"/update" + id} onClick={(event) => {
          event.preventDefault()
          setMode("UPDATE")
        }}>Update - 내용을 변경하세요.</a>
      </li>
    );
////////////////////////////////////////////////

	// 5️⃣
    else if (mode === "UPDATE") {
    content = <Update></Update>
  } 
    
////////////////////////////////////////////////
<ul>
   <li>
     <a
      href="/create"
      onClick={(event) => {
      event.preventDefault();
      setMode("CREATE");
      }}>
      Create - 새로운 항목을 추가하세요.
      </a>
    </li>
	  // 4️⃣
      {contextControl} 
 </ul>

1️⃣, 4️⃣ : UPDATE 기능은 맥락적으로 노출되는 UI로 만들어 준다.
2️⃣ : mode상태가 "READ" 일때만 나오도록 해준다.
3️⃣ : "contextControl"은 클릭되면 mode를 "UPDATE"로 변경해준다.
5️⃣ : mode가 "UPDATE"되면 content가 Update 컴포넌트가 되도록 한다.

UPDATE 입력값 가져오기

function Update(props) // 1️⃣ {
  return (
    <article>
      <h2>Update 페이지</h2>
      <form
        onSubmit={(event) => { // 2️⃣
          event.preventDefault();
          const title = event.target.title.value;
          const body = event.target.body.value;
          props.onUpdate(title, body); // 3️⃣
        }}
      >
        <p><input type="text" name="title" placeholder="title.."></input></p>
        <p><textarea name="body" placeholder="body.."></textarea></p>
        <p><input type="submit" value="Update!"></input></p>
      </form>
    </article>
  );
}

////////////////////////////////////////////////

else if (mode === "UPDATE") { // 4️⃣
    content = <Update onUpdate={(_title, _body) => {}}></Update>;
  }

1️⃣ : UPDATE 컴포넌트 생성
2️⃣ : UPDATE 내용 입력 후 제출
3️⃣ : props 함수인 4️⃣로 입력값 전달
4️⃣ : 컴포넌트로 입력받은 값을 가져와서 UPDATE 기능 수행

UPDATE전에 기존 내용 가져오기

} else if (mode === "UPDATE") {
    let title, body = null;

  	// 1️⃣
    topics.forEach((topic) => {
      if (topic.id === id) {
        title = topic.title;
        body = topic.body;
      }
    });
  
    content = (
      <Update
        title={title} // 2️⃣
        body={body} // 2️⃣
        onUpdate={(_title, _body) => {}}
      ></Update>
    );
  }
  
  /////////////////////////////////////////////
  
function Update(props) {
  return (
    <article>
      <h2>Update 페이지</h2>
      <form
        onSubmit={(event) => {
          event.preventDefault();
          const title = event.target.title.value;
          const body = event.target.body.value;
          props.onUpdate(title, body);
        }}
      >
        <p>
          <input
            type="text"
            name="title"
            placeholder="title.."
            value={props.title} // 3️⃣
          ></input>
        </p>
        <p>
          <textarea
            name="body"
            placeholder="body.."
            value={props.body} // 3️⃣
          ></textarea>
        </p>
        <p>
          <input type="submit" value="Update!"></input>
        </p>
      </form>
    </article>
  );
}

1️⃣ : "READ"에서 사용하던 title, body값을 가져온다.
2️⃣ : title, body 값을 props로 컴포넌트에 전달
3️⃣ : 컴포넌트에서 value 값으로 기존값을 그대로 호출한다.

🚫 기존 "READ" 항목의 값을 가져오지만 컴포넌트 내부에서 수정이 불가하다.

props로 전달된 값외부자값으로 컴포넌트 내에서는 수정이 불가하다.
컴포넌트 내에서 값을 수정하기 위해서는 내부자값 state로 변경해주어야 한다.

// props 값을 state값으로 바꾸기
function Update(props) {
  // 1️⃣
  const [title, setTitle] = useState(props.title)
  const [body, setBody] = useState(props.body)
    
  return (
    <article>
      <h2>Update 페이지</h2>
      <form
        onSubmit={(event) => {
          event.preventDefault();
          const title = event.target.title.value;
          const body = event.target.body.value;
          props.onUpdate(title, body);
        }}
      >
        <p>
          <input
            type="text"
            name="title"
            placeholder="title.."
            value={title} // 2️⃣
          ></input>
        </p>
        <p>
          <textarea
            name="body"
            placeholder="body.."
            value={body} // 2️⃣
          ></textarea>
        </p>
        <p>
          <input type="submit" value="Update!"></input>
        </p>
      </form>
    </article>
  );
}

1️⃣ : 외부자값 props를 컴포넌트 내부에서 사용하기 위해 내부자값 state로 변경
2️⃣ : 기존값 표시는 props값이 아닌 state의 값으로 한다.

입력값으로 UPDATE 하기

props의 값을 state 값으로 변경후에 내용을 수정하기 위해서는
⭐️ onChange()함수를 이용하여 state값을 set 해주어야 한다. ⭐️

function Update(props) {
  const [title, setTitle] = useState(props.title)
  const [body, setBody] = useState(props.body)
    
  return (
    <article>
      <h2>Update 페이지</h2>
      <form
        onSubmit={(event) => {
          event.preventDefault();
          const title = event.target.title.value;
          const body = event.target.body.value;
          props.onUpdate(title, body); // 2️⃣
        }}
      >
        <p>
          <input
            type="text"
            name="title"
            placeholder="title.."
            value={title}
            onChange={(event) => {
              setTitle(event.target.value); // 1️⃣
            }}
          ></input>
        </p>
        <p>
          <textarea
            name="body"
            placeholder="body.."
            value={body} 
            onChange={(event) => {
              setBody(event.target.value); // 1️⃣
            }}
          ></textarea>
        </p>
        <p>
          <input type="submit" value="Update!"></input>
        </p>
      </form>
    </article>
  );
}

////////////////////////////////////////////////

} else if (mode === "UPDATE") {
    let title, body = null;

    topics.forEach((topic) => {
      if (topic.id === id) {
        title = topic.title;
        body = topic.body;
      }
    });
  
    content = (
      <Update
        title={title}
        body={body}
        onUpdate={(_title, _body) => { // 3️⃣
          // 4️⃣
          const newTopics = topics.map((topic) => { 
            // id값은 수정되는 항목의 id값 그대로 가져온다 (update 니깐)
            let newTopic = { id: id, title: _title, body: _body };
            if (topic.id === id) {
              return (topic = newTopic);
            }
            return topic;
          });
          setTopics(newTopics); // 5️⃣
          setMode("READ")
        }}
      ></Update>
    );
  }

1️⃣ : 컴포넌트의 onChange()함수로 입력값을 UPDATE하고
2️⃣ : submit하면 props의 함수로 수정값을 전달하면서 실행한다.
3️⃣ : onUpdate 실행
4️⃣ : 오리지날 topics를 map메서드를 활용해 수정된 새로운 배열로 반환한다.
5️⃣ : 새로운 topics배열로 상태를 변경해준다. -> 리렌더링

profile
한 발자국, 한 걸음 느리더라도 하루하루 발전하는 삶을 살자.

0개의 댓글