티스토리 뷰
대부분의 어플리케이션은 CRUD 기능을 가지고 있으며 지난 강의까지는 Read를 구현했다.
지금부터는 Create를 구현해보자
state를 만들 때 원시 데이터 타입이라면 기존 방식대로 생성하면 된다
하지만 객체,배열 같이 범 객체 안에 들어간다면 처리 방법이 달라진다.
데이터를 복제 후 복제 본을 변경한다.
그 후 setValue에 newValue를 넣어주면 component가 다시 실행된다.
여기서 핵심은 오리지널 데이터를 건들지않고 복제본을 변경하는 것이다.
why?
React는 오리지널 데이터와 새로 들어온 데이터가 같은 데이터인지 확인 후 같다면 component를 재실행 하지 않음
위) 객체 타입일 때 state 생성 예시
아래) 원시 타입일 때 state 생성 예시
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 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;
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>
}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>
}
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}
<a href = "/create" onClick={event=>{
event.preventDefault(); //url 바뀌는 것 방지
setMode('CREATE');
}}>Create</a>
</div>
);
}
export default App;
Create 클릭 후 글 입력 시 본문에 추가 기능
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 프리프로젝트
- 프로젝트
- 인적성
- Redux
- 코드스테이츠
- 코테
- 기술면접
- 스택오버플로우
- SEB 43
- 감정 일기장
- dictionary
- 백준
- 그리디 알고리즘
- 개인 프로젝트
- SEB 43기
- 프로그래머스
- dfs
- 감정일기장
- Python
- React quill
- SEB43기
- 브루드포스
- BFS
- 회고
- 다이나믹 프로그래밍
- SEB43
- 프론트엔드
- seb
- til
- 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 |
글 보관함