DEVELOP
article thumbnail

인프런 이정한님의 한입크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지 ] 강의 수강 후 강의의 내용을 정리하며 공부한 것을 쓴 게시글입니다.

 

한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지 - 인프런 | 강의

개념부터 독특한 프로젝트까지 함께 다뤄보며 자바스크립트와 리액트를 이 강의로 한 번에 끝내요. 학습은 짧게, 응용은 길게 17시간 분량의 All-in-one 강의!, - 강의 소개 | 인프런...

www.inflearn.com


1. React에서 사용자 입력 처리하기

- DiaryEditor 컴포넌트가 필요한 것 

  • 작성자
  • 일기본문 
  • 감정 점수

- 작성자, 일기 본문, 감정 점수를 state로 저장하고 변경한다. 

- 하나의 state로 객체 배열을 관리할 수 있다. 

- 초기값은 빈 문자열과 1로 설정한다. 

<javascript />
const [state, setState] = useState({ author: "", content: "", emotion: 1 });

- setState를 할 때에는 spread 연산자(...)를 이용해, 바꾸고자 하는 것을 제외하고는 원본을 유지한다. 

- [e.target.name]: e.target.value 

      ->  state배열 원소 중  e.target.name 의 값을 key로  가진 객체의 value값을 e.target.value로 바꾼다. 

<javascript />
const handleChangeState = (e) => { setState({ ...state, [e.target.name]: e.target.value }); };

- onChange : value 변화를 감지

- onClick : Click Event 감지

- 작성자

<javascript />
<input name="author" value={state.author} placeholder="author" onChange={handleChangeState} />

- 일기 본문

<javascript />
<textarea name="content" value={state.content} placeholder="content" onChange={handleChangeState} />

- 감정 점수

<javascript />
<span>오늘의 감정점수 : </span> <select name="emotion" value={state.emotion} onChange={handleChangeState}> <option value={1}>1</option> <option value={2}>2</option> <option value={3}>3</option> <option value={4}>4</option> <option value={5}>5</option> </select>

- 저장 버튼 

<javascript />
<button onClick={handleSubmit}>저장</button>

일기 작성 폼


2. React에서 DOM 조작하기

2.1. # DiaryEditor.js

-  useRef로 특정 DOM 선택하기

<javascript />
const authorInput = useRef(); const contentInput = useRef();

 

- input 태그와 textarea 태그 각각에 ref={authorInput}, ref={contentInput} 추가 

 

- handleSubmit 함수 수정 

- 작성자 이름이 1글자 미만이면 저장되지 않고, 작성자 이름 입력 칸으로 focus

- 일기 본문이 5글자 미만이면, 저장되지 않고, 일기 본문 입력 칸으로 focus

<javascript />
const handleSubmit = () => { if (state.author.length < 1) { authorInput.current.focus(); return; } if (state.content.length < 5) { contentInput.current.focus(); return; } alert("저장 성공!"); }

작성자가 1글자 미만일 때 작성자 입력 칸으로 focus
내용이 5글자 미만일 때 내용 입력 칸으로 focus


3. React에서 배열 사용하기 (CRUD)

3.1. # App.js 

- 일기 리스트를 저장할 배열 data - state로 사용 

<javascript />
const [data, setData] = useState([]);

- 각각의 일기의 아이디 값을 저장할 dataId - ref로 사용 

 

<javascript />
const dataId = useRef(0);

- 일기 생성 시 호출 할 함수 : onCreate 

   - 새로운 객체를 생성하고, 기존 배열에 새로운 객체를 포함하여 setData 함 
   - DiaryEdit 호출 시 onCreate 함수를 전달 :  <DiaryEditor onCreate={onCreate} />

   - 기존 저장 버튼을 눌렀을 때 실행되던 함수에 onCreate 추가해 data를 저장하게 함

<javascript />
const onCreate = (author, content, emotion) => { const created_date = new Date().getTime(); const newItem = { author, content, emotion, created_date, id: dataId.current, }; dataId.current += 1; setData([newItem, ...data]); };

일기 저장후 리스트 생성된 화면

- 일기 삭제 시 호출할 함수 : onRemove

    - 삭제 할 일기의 id를 targetId로 전달받아 해당 id의 객체를 제외한 나머지 객체들로 새 객체 생성 해 setData

<javascript />
const onRemove = (targetId) => { const newDiaryList = data.filter((it) => it.id !== targetId); setData(newDiaryList); };

- 일기 수정 시 호출할 함수 : onEdit 

  - 수정 할 일기의 id를 targetId로 전달받고, map으로 배열을 돌면서  해당 id의 객체의 content를 전달받은 newContent 값으로 바꿈

<javascript />
const onEdit = (targetId, newContent) => { setData( data.map((it) => it.id === targetId ? { ...it, content: newContent } : it ) ); };

    - DiaryList 호출 시 onRemove 함수와 onEdit 함수를 전달하고, DiaryList에서 DiaryItem을 호출할 때 두 함수를 넘겨 받음

     <DiaryList onRemove={onRemove} onEdit={onEdit} diaryList={data} />
     <DiaryItem key={it.id} {...it} onRemove={onRemove} onEdit={onEdit} />

3.2. # DiaryList.js

- 전달받은 diaryList 를 map으로 돌며, 각각의 일기의 DiaryItem을 생성 

<javascript />
const DiaryList = ({ onRemove, onEdit, diaryList }) => { return ( <div className="DiaryList"> <h2>일기 리스트</h2> <h4>{diaryList.length}개의 일기가 있습니다.</h4> <div> {diaryList.map((it) => ( <DiaryItem key={it.id} {...it} onRemove={onRemove} onEdit={onEdit} /> ))} </div> </div> ); };

3.3. # DiaryItem.js

- 수정작업 중일 때를 뜻하는 isEdit -  state로 사용하고, 기본 값은 false

- toggleEdit 함수는 toggle 처럼 isEdit이 true값일때는 false로, false 값일 때는 true 값으로 바꿈

<javascript />
const [isEdit, setIsEdit] = useState(false); const toggleIsEdit = () => setIsEdit(!isEdit);

- 수정 중인 일기의 내용의 값인 localContent - state로 사용 

<javascript />
const [localContent, setLocalContent] = useState(content);

- 삭제 버튼 클릭하면 호출되는 함수 : handleRemove 

    - 사용자에게 삭제할 것인지 물어보고, 확인을 클릭하면 App.js에서 선언한 onRemove 함수 호출

<javascript />
const handleRemove = () => { if (window.confirm(`${id + 1}번째 일기를 삭제하시겠습니까?`)) { onRemove(id); } };

일기 삭제

- 수정 버튼을 클릭하고, 수정 후 완료 벼튼을 클릭하면 호출되는 함수 : handleEdit

    - 사용자가 수정한 내용의 글자 수가 5 미만이라면, 해당 입력 칸에 focus하여 다시 입력하도록 함

    - 사용자에게 수정할 것인지 물어보고, 확인 버튼을 클릭하면, App.js에서 선언한 onEdit 함수 호출 

    - isEdit을 다시 false로 바꾸도록 toggleEdit 함수 호출  

<javascript />
const handleEdit = () => { if (localContent.length < 5) { localContentInput.current.focus(); return; } if (window.confirm(`${id + 1}번째 일기를 수정하시겠습니까?`)) { onEdit(id, localContent); toggleIsEdit(); } };

일기 수정 완료

- 일기 수정 중에 (수정)취소 버튼 클릭하면 호출 되는 함수 : handleQuitEdit 

   - isEdit을 false로 바꾸고, 화면에 보이는 일기의 내용을 원래의 값으로 다시 보여지도록 함 

<javascript />
const handleQuitEdit = () => { setIsEdit(false); setLocalContent(content); };

일기 수정 취소

- 수정 중임을 나타내는 isEdit의 값이 true일 때는 textarea로 수정할 수 있도록 하고, false일 때는, 해당 일기의 content값이 보여지도록 함 

<javascript />
<div className="content"> {isEdit ? ( <> <textarea ref={localContentInput} value={localContent} onChange={(e) => setLocalContent(e.target.value)} /> </> ) : ( <>{content}</> )} </div>

- isEdit이 true이면 (수정)취소, (수정)완료 버튼이 보여지도록 하고, false이면 삭제, 수정 버튼이 보여지도록 함 

<javascript />
{isEdit ? ( <> <button onClick={handleQuitEdit}>취소</button> <button onClick={handleEdit}>완료</button> </> ) : ( <> <button onClick={handleRemove}>삭제</button> <button onClick={toggleIsEdit}>수정</button> </> )}

 

profile

DEVELOP

@JUNGY00N