💡 Update

  • UPDATE 는 CREATE 와 READ를 하이브리드해서 구현

UPDATE = CREATE + READ


# Update 링크 추가

function App() {
  const [mode, setMode] = useState('WELCOME');
  const [id, setId] = useState(null);
  const [nextId, setNextId] = useState(4); 
  const [topics, setTopics] = useState([ 
    {id: 1, title: 'HTML', body: 'HTML is ...'},
    {id: 2, title: 'CSS', body: 'CSS is ...'},
    {id: 3, title: 'JavaScript', body: 'JavaScript is ...'},
  ]);
  let content = null;
  // 📍 새로운 지역변수 
  let contextControl = null;
  if (mode === 'WELCOME') {
    content = <Article title="Welcome" body="Hello, WEB"></Article>
  } else if (mode === 'READ') {
    let title, body = null;
    for (let i = 0; i < topics.length; i++) {
      if (topics[i].id === id) {
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Article title={title} body={body}></Article>
     // 📍 Update 링크, id 값 추가
    contextControl = <li><a href={'/update/'+id} onClick={(event) => {
      event.preventDefault();
      setMode('UPDATE');
    }}>Update</a></li>
      
*** 생략 ***
      
return (
    <div>
      <Header title="WEB" onChangeMode={() => {
        setMode('WELCOME');
      }}></Header>
      <Nav topics={topics} onChangeMode={(_id) => {
        setMode('READ');
        setId(_id);
      }}></Nav>
      {content}
      <ul>   // 📍 목록화
        <li>  
          <a href="/create" onClick={(event) => {
          event.preventDefault();
          setMode('CREATE'); 
          }}>Create</a>
        </li>
        // 📍 Update 링크
        {contextControl}
      </ul>
    </div>
  );

# Update 작동 코드 작성하기

// 📍 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);
      }}>
        { // 📍 value 값 props.title, body 추가
          // ❓내용 수정이 불가함
        <p><input type="text" name="title" placeholder="title" value={props.title}></input></p>
        <p><textarea name="body" placeholder='body' value={props.body}></textarea></p>
        <input type="submit" value="Update"></input>
      </form>
    </article>
  )
}

** 생략 **
  
} else if (mode === 'UPDATE') {
    // 📍 title, body에 기본값 들어있게 하기
    let title, body = null;
      for (let i = 0; i < topics.length; i++) {
        if (topics[i].id === id) {
          title = topics[i].title;
          body = topics[i].body;
        }
      }
    content = <Update title={title} body={body} onUpdate={(title, body) => {
    }}></Update>
  }

❗️ 문제점 " title, body 값 수정할 수 있게 바꾸기 "

  • props는 사용자가 컴포넌트로 전달한 명령
    → 💡 prop을 state로 바꾸기
function Update(props) {
  // 📍 prop을 state로 바꾸기
  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);
      }}>
        { // 📍 props를 onChange로
        <p><input type="text" name="title" placeholder="title" value={title} onChange={(event) => {
          setTitle(event.target.value);  // 📍 새로운 state로 바꾸기
        }}></input></p>
        <p><textarea name="body" placeholder='body' value={body} onChange={(event) => {
          setBody(event.target.value);   // 📍 새로운 state로 바꾸기
        }}></textarea></p>
        <input type="submit" value="Update"></input>
      </form>
    </article>
  )
}

# Update 된 값으로 topics 변경하기

} else if (mode === 'UPDATE') {
    let title, body = null;
      for (let i = 0; i < topics.length; i++) {
        if (topics[i].id === id) {
          title = topics[i].title;
          body = topics[i].body;
        }
      }
    content = <Update title={title} body={body} onUpdate={(title, body) => {
      // 📍 Update 된 값으로 topics 변경하기
      const newTopics = [...topics]  // 📍 topics 복제
      const updatedTopic = {id: id, title: title, body: body}
      for (let i = 0; i < newTopics.length; i++) {
        if(newTopics[i].id === id) {
          newTopics[i] = updatedTopic;
          break;
        }
      }
      setTopics(newTopics);
      setMode('READ');  // 📍 수정한 내용 바로 보이게
    }}></Update>
  }

# 완성

import './App.css';
import {useState} from 'react';

function Header (props) {
  console.log('props', props, props.title);
  return (
  <header>
    <h1><a href="/" onClick={(event) => {
      event.preventDefault();
      props.onChangeMode();
    }}>{props.title}</a></h1>
  </header>
  )
}
function Nav (props) {
  const lis = [];
  for (let i = 0; i < props.topics.length; i++) {
    let t = props.topics[i];
    lis.push(
      <li key={t.id}>  
        <a href={'/read/'+t.id} onClick={(event) => {
          event.preventDefault();
          props.onChangeMode(Number(t.id));
        }}>{t.title}</a>
      </li>
    )
  }
  return (
    <nav>
      <ol>
        {lis}
      </ol>
    </nav>
  )
}
function Article (props) {
  return (
    <article>
      <h2>{props.title}</h2>
      {props.body}
    </article>
  )
}
function Create (props) {
  return (
    <article>
      <h2>Create</h2>
      <form onSubmit={(event) => {  
        event.preventDefault();  
        const title = event.target.title.value; 
        const body = event.target.body.value;  
        props.onCreate(title, body);
      }}>
        <p><input type="text" name="title" placeholder="title"></input></p>
        <p><textarea name="body" placeholder='body'></textarea></p>
        <input type="submit" value="Create"></input>
      </form>
    </article>
  )
}
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);
      }}>
        <p><input type="text" name="title" placeholder="title" value={title} onChange={(event) => {
          setTitle(event.target.value); 
        }}></input></p>
        <p><textarea name="body" placeholder='body' value={body} onChange={(event) => {
          setBody(event.target.value); 
        }}></textarea></p>
        <input type="submit" value="Update"></input>
      </form>
    </article>
  )
}
function App() {
  const [mode, setMode] = useState('WELCOME');
  const [id, setId] = useState(null);
  const [nextId, setNextId] = useState(4); 
  const [topics, setTopics] = useState([ 
    {id: 1, title: 'HTML', body: 'HTML is ...'},
    {id: 2, title: 'CSS', body: 'CSS is ...'},
    {id: 3, title: 'JavaScript', body: 'JavaScript is ...'},
  ]);
  let content = null;
  let contextControl = null;
  if (mode === 'WELCOME') {
    content = <Article title="Welcome" body="Hello, WEB"></Article>
  } else if (mode === 'READ') {
    let title, body = null;
    for (let i = 0; i < topics.length; i++) {
      if (topics[i].id === id) {
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Article title={title} body={body}></Article>
    contextControl = <li><a href={'/update/'+id} onClick={(event) => {
      event.preventDefault(); 
      setMode('UPDATE');
    }}>Update</a></li>
  } else if (mode === 'CREATE') {
    content = <Create onCreate={(_title, _body) => {
      const newTopic = {id: nextId, title: _title, body: _body,}
      const newTopics = [...topics] 
      newTopics.push(newTopic); 
      setTopics(newTopics);
      setMode('READ');
      setId(nextId);  
      setNextId(nextId + 1);
    }}></Create>
  } else if (mode === 'UPDATE') {
    let title, body = null;
      for (let i = 0; i < topics.length; i++) {
        if (topics[i].id === id) {
          title = topics[i].title;
          body = topics[i].body;
        }
      }
    content = <Update title={title} body={body} onUpdate={(title, body) => {
      const newTopics = [...topics] 
      const updatedTopic = {id: id, title: title, body: body}
      for (let i = 0; i < newTopics.length; i++) {
        if(newTopics[i].id === id) {
          newTopics[i] = updatedTopic;
          break;
        }
      }
      setTopics(newTopics);
      setMode('READ');
    }}></Update>
  }
  return (
    <div>
      <Header title="WEB" onChangeMode={() => {
        setMode('WELCOME');
      }}></Header>
      <Nav topics={topics} onChangeMode={(_id) => {
        setMode('READ');
        setId(_id);
      }}></Nav>
      {content}
      <ul>
        <li>  
          <a href="/create" onClick={(event) => {
          event.preventDefault();
          setMode('CREATE'); 
          }}>Create</a>
        </li>
        {contextControl}
      </ul>
    </div>
  );
}

export default App;

📍 주의할 점

  • 수정일 경우 기존의 값이 value 값으로 주입되었을 경우 prop에서 state로 갈아탄다
  • 값이 바뀔때 마다 바뀐 값을 state로 바꿔서 그 값을 feedback 받아야 한다

✨ 끝 !

✦ 출처 : 생활코딩 [React 2022년 개정판]

profile
✧ 중요한건 꺾이지 않는 마음 🔥 ᕙ(•ө•)ᕤ 🔥

0개의 댓글

Powered by GraphCDN, the GraphQL CDN