1. Create
content = (
<Create
onCreate={(_title, _body) => {
// topics에 id, title, body 추가하기
const newTopic = { id: nextId, title: _title, body: _body };
const newTopics = [...topics];
newTopics.push(newTopic);
setTopics(newTopics);
setNextId(nextId + 1);
}}
></Create>
);
배열의 상태를 변경시킬 때는
1) newValue = {...value} → ...을 통해 똑같은 배열을 복사한 newValue를 만든다
2) newValue 변경 → 복사된 배열을 변경시킨다
3) setValue(newValue) → 컴포넌트를 다시 실행시켜 변경된 내용으로 배열을 만든다.
2. Update
Update는 Create + Read를 통해 만들 수 있다.
# Update 컴포넌트
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);
}}
/>
<textarea
name="body"
placeholder="body"
value={body}
onChange={(event) => {
setBody(event.target.value);
}}
></textarea>
</p>
<p>
<input type="submit" value="Update"></input>
</p>
</form>
</article>
);
}
기존의 값이 value로 들어왔을 때는 이를 useState를 사용해 state로 바꿔서 수정이 가능한 상태로 만들어야한다.
그렇지 않으면, text를 수정할 수 없어서 update를 할 수 없다.
위 코드에서는 두 번째, 세 번째 줄이 props를 통해 외부에서 가지고 온 기존의 값을 state로 바꾸는 작업이다.
또한, state로 바꾼 뒤에 수정한 값은, 수정이 될 때마다 onChage를 통해 계속 피드백을 받아야한다.
3. Delete
배열에서 delete를 할 때에는 새로운 배열을 만들어 특정 요소만 제외한 채로 담고, 그 상태를 setTopics()로 바꿔주는 것으로 할 수 있다.
<li>
<input
type="button"
value="Delete"
onClick={() => {
const newTopics = [];
for (let i = 0; i < topics.length; i++) {
if (topics[i].id != id) {
newTopics.push(topics[i]);
}
}
setTopics(newTopics);
setMode("WELCOME");
}}
/>
</li>
4. 전체 코드
import logo from "./logo.svg";
import "./App.css";
import { useState } from "react";
function Header(props) {
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
id={t.id}
href={"/read/" + t.id}
onClick={(event) => {
event.preventDefault();
props.onChangeMode(Number(event.target.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" />
<textarea name="body" placeholder="body"></textarea>
</p>
<p>
<input type="submit" value="Create"></input>
</p>
</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);
}}
/>
<textarea
name="body"
placeholder="body"
value={body}
onChange={(event) => {
setBody(event.target.value);
}}
></textarea>
</p>
<p>
<input type="submit" value="Update"></input>
</p>
</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: "jabascript", body: "jabascript 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>
<li>
<input
type="button"
value="Delete"
onClick={() => {
const newTopics = [];
for (let i = 0; i < topics.length; i++) {
if (topics[i].id != id) {
newTopics.push(topics[i]);
}
}
setTopics(newTopics);
setMode("WELCOME");
}}
/>
</li>
</>
);
} else if (mode === "CREATE") {
content = (
<Create
onCreate={(_title, _body) => {
// topics에 id, 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="REACT"
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;
'Front-End' 카테고리의 다른 글
[React] state (0) | 2023.08.17 |
---|---|
[React] 이벤트 (0) | 2023.08.17 |
[React] Props (0) | 2023.08.16 |
[React] 컴포넌트 만들기(사용자 정의 태그) (0) | 2023.08.16 |
[React] 기초 환경 세팅, 코드 수정, 배포 (0) | 2023.08.14 |