티스토리 뷰
Update는 Create와 Read를 합친 난이도 있는 작업
function Update(props){
const [title, setTitle] =useState(props.title); //props에 들어온 title에서 state로
const [body, setBody] =useState(props.body);
return <article>
<h2>Update</h2>
<form onSubmit={event=>{
event.preventDefault();
const title = event.target.title.value; //event target은 form 태그 지칭
const body = event.target.body.value;
props.onUpdate(title,body);
}}>
<p><input type="text" name="title" placeholder="title" value={title} onChange={event=>{//state를 value값으로 줌
setTitle(event.target.value); //새로 입력할때 마다 setTitle지정, 컴포넌트 다시 실행
}}/></p>
<p><textarea name="body" placeholder="body" value={body} onChange={event=>{//state를 value값으로 줌
setBody(event.target.value); //새로 입력할때 마다 setTitle지정, 컴포넌트 다시 실행
}}></textarea></p>
<p><input type="submit" value="Update"></input></p>
</form>
</article>
//기존 내용이 저장되게 value값을 설정해줌
//react에서는 값을 입력할 때마다 onChange 발생
}
Update에서 주의 사항
기존의 값이 value값으로 주입 되었을 때, prop에서 state로 변경하고 값이 바뀔 때마다 바뀐 값을 state로 바꿔서 그 값을 다시 피드백 받아야 한다.
Update를 클릭해서 본문 내용 변경
App.js
import logo from './logo.svg';
import './App.css';
import {useState} from 'react'; //state 사용
function Header(props){//컴포넌트 생성(대문자로 시작)
return <header>
<h1><a href="/" onClick={(event)=>{ //event객체를 첫번째 파라미터로
event.preventDefault(); //<a>태그 의 기본동작 방지-> reload 되지 않게
props.onChangeMode(); // alert 호출
}}>{props.title}</a></h1>
</header>
}
function Nav(props){
const lis =[]
for(let i=0; i<props.topics.length; i++){ //topics의 개수만큼 반복
let t = props.topics[i];
lis.push(<li key={t.id}>
<a id={t.id} href={'/read/'+t.id} onClick={(event)=>{ //id값을 부여해주기
event.preventDefault();
props.onChangeMode(Number(event.target.id)); //event를 동작시킨 태그의 id
//문자가 된 데이터를 숫자로 변환
}}>{t.title}</a></li>) //lis에 하나씩 넣기, 동적으로 바뀔대상이 있으면 중괄호 사용
//<li>태그가 구별되도록 key값을 고유값으로 설정
}
return <nav>
<ol>
{lis}
</ol>
</nav>
}
function Article(props){//props를 사용시 함수 외부에서 입력값으로 사용가능
return <article>
<h2>{props.title}</h2>
{props.body}
</article>
}
function Create(props){ //Create 컴포넌트 생성
//텍스트 제목과 텍스트 영역, Create 버튼 생성
return <article>
<h2>Create</h2>
<form onSubmit={event=>{
event.preventDefault();
const title = event.target.title.value; //event target은 form 태그 지칭
const body = event.target.body.value;
props.onCreate(title,body);
}}>
<p><input type="text" name="title" placeholder="title"/></p>
<p><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); //props에 들어온 title에서 state로
const [body, setBody] =useState(props.body);
return <article>
<h2>Update</h2>
<form onSubmit={event=>{
event.preventDefault();
const title = event.target.title.value; //event target은 form 태그 지칭
const body = event.target.body.value;
props.onUpdate(title,body);
}}>
<p><input type="text" name="title" placeholder="title" value={title} onChange={event=>{//state를 value값으로 줌
setTitle(event.target.value); //새로 입력할때 마다 setTitle지정, 컴포넌트 다시 실행
}}/></p>
<p><textarea name="body" placeholder="body" value={body} onChange={event=>{//state를 value값으로 줌
setBody(event.target.value); //새로 입력할때 마다 setTitle지정, 컴포넌트 다시 실행
}}></textarea></p>
<p><input type="submit" value="Update"></input></p>
</form>
</article>
//기존 내용이 저장되게 value값을 설정해줌
//react에서는 값을 입력할 때마다 onChange 발생
}
function App() {
//const _mode = useState('WELCOME'); //mode의 값에 따라 본문 변화
//const mode = _mode[0]; //상태의 값 읽기 가능
//const setMode = _mode[1]; //mode의 값을 바꿀 수 있음
const [mode, setMode] = useState('WELCOME');
const [id, setId] = useState(null);
const [nextId, setNextId] =useState(4); //state의 초기값의 id가 4
const [topics, setTopics] = useState([ //state로 승격시키기
{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'){ //mode의 따라 결정
content = <Article title="Welcome" body="Hello, WEB"></Article>
}else if(mode === 'READ'){
let title, body = null;
for(let i=0; i<topics.length; i++){ //topics.id와 id state가 일치하면 title,body 값 설정
console.log(topics[i].id, id);
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'); //mode를 UPDATE로 변경
}}>Update</a></li> //mode가 READ일 때만 나타나기
}else if(mode === 'CREATE'){
content = <Create onCreate={(_title, _body)=>{ //Create버튼 눌렀을 때 실행함수
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'){
//title과 body 알아내기 위해 앞의 코드 복사
let title, body = null;
for(let i=0; i<topics.length; i++){ //topics.id와 id state가 일치하면 title,body 값 설정
console.log(topics[i].id, id);
if(topics[i].id === id){
title = topics[i].title;
body = topics[i].body;
}
}
content = <Update title={title} body={body} onUpdate={(title,body)=>{
console.log(title,body);
const newTopics = [...topics] //기존 토픽 복제
const updatedTopic = {id:id, title:title, body:body} //수정할 토픽 생성
for(let i=0; i<newTopics.length; i++){ //기존토픽과 일치하는 id찾기
if(newTopics[i].id === id){
newTopics[i] = updatedTopic;
break;
}
}
setTopics(newTopics); //토픽이 바뀌면 컴포넌트 새로 실행
setMode('READ');
}}></Update>
}
return (
<div>
<Header title="WEB" onChangeMode={()=>{ // onChangeMode prop값으로 함수 호출, function() == ()=>
setMode('WELCOME'); //값을 바꿀 때는 setMode
}}></Header>
<Nav topics={topics} onChangeMode={(_id)=>{ //id값을 입력받는 함수 호출
setMode('READ'); //값을 바꿀 때는 setMode
setId(_id); //_id값이 바뀌면 컴포넌트가 새로 실행되며 새로운 id값 지정 해줌
}}></Nav>
{content}
<ul>
<li><a href = "/create" onClick={event=>{
event.preventDefault(); //url 바뀌는 것 방지
setMode('CREATE');
}}>Create</a></li>
{contextControl}
</ul>
</div>
);
}
export default App;
변경된 화면
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- React quill
- 스택오버플로우
- SEB43
- 회고
- 그리디 알고리즘
- SEB 43
- 프로젝트
- dfs
- 감정일기장
- 브루드포스
- seb
- 기술면접
- dictionary
- 감정 일기장
- 백준
- Python
- SEB 43기
- 프론트엔드
- SEB43기
- 프로그래머스
- BFS
- 다이나믹 프로그래밍
- til
- 코테
- 인적성
- 코드스테이츠
- 개인 프로젝트
- Redux
- 프리프로젝트
- useContext
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함