UPDATE = CREATE + READ
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 함수 만들기
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>
}
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>
)
}
} 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년 개정판]