Search
🍔

React로 CRUD 구현하기

Created
2023/05/16
Tags
React
Category
Project
Parent item
Sub-item
2 more properties

구현할 기능

As-Is: 현재는 기존에 올라온 글을 볼 수 있기만 함
To-be: 맛집 제보 버튼을 클릭하면 포스팅 업로드가 가능하도록 하기

구현 과정 - Create

1. input 칸을 만든다.

input의 타입은 아래와 같이 다양하니 골라서 활용해 보자.
<input type = "date" />
<input type = "range" />
<input type = "checkbox" />
<input type = "input" /> or 그냥 <input/>
<input/> <select/>
<textarea/>

2. onChange 이벤트 핸들러를 활용한다.

onChange 또는 onInput라는 이벤트 핸들러를 사용해 사용자가 <input>에 무언가 입력 시, 중괄호 안에 있는 코드가 실행되도록 한다.
<input onChange={() => {console.log("사용자가 입력하면 나타나는 내용")}} />
JavaScript
복사
아래와 같이 사용자가 무언가를 입력하면, 안에 있는 코드가 실행되는 것이 보인다. 이외에도 스크롤, 마우스 오버 등등 수많은 이벤트 핸들러들이 있는데, 이는 굳이 외울 필요는 없고 필요할 때마다 그때그때 갖다 쓰면 된다.

3. input에 입력한 값을 가져온다.

파라미터를 하나 추가한다. 아무거나 써도 되며 내가 입력한 e는 보통 이벤트 객체라는 역할을 하는데, input 태그에서 발생하는 이벤트에 관련된 여러 기능들이 이 파라미터 안에 담겨 있다. 이 e.target을 붙이면 해당 이벤트가 발생한 html 태그가 무엇인지 알려준다.
<input onChange={(e) => {console.log(e.target)}} />
JavaScript
복사
더불어, e.target 뒤에 .value를 붙이면, 해당 이벤트가 발생한 html 태그에 입력한 '값'이 나온다. 따라서 '입력'이라고 입력하면 ㅇ부터 마지막 ㄱ까지 콘솔에 찍힌다.
<input onChange={(e) => {console.log(e.target.value)}} />
JavaScript
복사

4. input에 입력한 값을 저장한다.

사용자가 입력한 값은 보통 변수나 state에 저장해 두는데, 여기서는 state와 state 변경 함수를 만들어서 아까 써둔 console.log 부분에 넣어주자. 그럼 사용자가 입력한 값이 state에 저장된다.
let [inputValue, setInputValue] = useState(''); // ... 생략 <input onChange={(e) => {setInputValue(e.target.value)}} />
JavaScript
복사
어?
그런데 처음에 입력한 값이 콘솔에 찍히지 않고, 두 번째 입력한 값부터 찍힌다. 왜 그럴까?
state 변경 함수는 늦게 처리가 되기 때문이다. 바로 '비동기적'으로 처리가 되기 때문이다. 즉, state가 변경되기 전에 console에 있는 줄을 실행해 주는 것이다.

구현 과정 - Read, Update

1. state 변경 함수를 사용한다.

새로운 글이 추가되도록 하려면 입력된 내용을 저장하고 표시해야 한다. 현재 inputValue라는 state 변경 함수를 사용하여 입력된 내용을 저장하고 있으므로 이 state 변경 함수를 사용하여 새로운 글을 추가할 수 있다.
그리고 addPost 함수를 추가로 선언해 주었는데, 이 함수는 입력된 내용(inputValue)을 새로운 글로 추가하고, 제목과 좋아요 버튼의 배열을 업데이트한 후, inputValue를 초기화하는 역할을 한다. 따라서 사용자가 특정 버튼을 눌러 하나의 글이 추가될 때 업데이트 되어야 할 것들(제목, 좋아요 버튼, 입력란)을 addPost 함수의 조건문 안에 넣어준다.
// ...생략 function App() { let report = '🧁 나만 아는 맛집 제보하기'; let [title, setTitle] = useState(['성수역', '강남역', '압구정역']); let [thumb, setThumb] = useState([0, 0, 0]); let [modal, setModal] = useState(false); let [modalTitle, setModalTitle] = useState(0); let [inputValue, setInputValue] = useState(''); // 맛집 제보하기 버튼 const addPost = () => { // 글이 생성되면 if (inputValue) { setTitle([...title, inputValue]); // 제목 업데이트 setThumb([...thumb, 0]); // 좋아요 버튼 업데이트 setInputValue(''); // 입력란 초기 상태로 업데이트 } }; // ...생략
JavaScript
복사

2. onClick 이벤트로 함수를 연결한다.

버튼에 onClick 이벤트로 addPost 함수를 연결하여 클릭할 때 새로운 글이 추가되도록 한다.
// ...생략 return ( // ...생략 {/* 추천 맛집 입력란 */} <textarea className='reportArea' placeholder = "추천 맛집이 있나요?" value={inputValue} onChange={(e) => {setInputValue(e.target.value);}} /> <p/> {/* 맛집 제보 버튼 */} <button className='reportButton' onClick={addPost}>// 버튼 클릭시 글 생성 { report }</button> <p/> </div> ); } export default App;
JavaScript
복사
이제 내용을 입력창에 입력한 후, 맛집 제보 버튼을 클릭하면 새로운 글이 추가될 것이다.

구현 과정 - Delete

1. splice를 사용해 배열이 업데이트 되도록 만든다.

글을 삭제할 수 있는 기능을 구현하려면 각 글에 대한 삭제 버튼을 추가하고, 해당 버튼이 클릭되었을 때 해당 글을 제거해야 한다. 글 추가 기능 구현과 마찬가지로 deletePost 함수를 추가했다. 이 함수는 인덱스를 받아와서 해당 인덱스에 있는 글의 제목과 좋아요 버튼을 배열에서 제거하는 역할을 하며, splice 메소드를 사용하여 원본 배열을 업데이트한다.
// ...생략 function App() { let report = '🧁 나만 아는 맛집 제보하기'; let [title, setTitle] = useState(['성수역', '강남역', '압구정역']); let [thumb, setThumb] = useState([0, 0, 0]); let [modal, setModal] = useState(false); let [modalTitle, setModalTitle] = useState(0); let [inputValue, setInputValue] = useState(''); // ... 생략 // 제보한 맛집 삭제 const deletePost = (index) => { // 삭제 함수는 index를 받아옴 const newTitle = [...title]; const newThumb = [...thumb]; newTitle.splice(index, 1); // splice로 제목 배열 업데이트 newThumb.splice(index, 1); // splice로 좋아요 버튼 배열 업데이트 setTitle(newTitle); setThumb(newThumb); }; // ... 생략
JavaScript
복사

2. 삭제 버튼을 추가한다.

또한, title.map() 메서드 내에서 각 post에 대한 삭제 버튼을 추가했다. 버튼에 onClick 이벤트로 deletePost(i)를 연결하여 클릭할 때 해당 글을 삭제하도록 한다. i는 현재 글의 인덱스다.
// ...생략 <p className="share">📮 공유하기</p> <button className="deleteButton" onClick={() => deletePost(i)} >삭제</button> {/* onClick으로 삭제 이벤트 생성 */} </div>) }) } </div> ); } export default App;
JavaScript
복사
이제 각 글 옆에 추가된 삭제 버튼을 클릭하면 해당 글이 삭제될 것이다.

구현된 화면