저번 포스트에서 만든 create 기능에 더해서 update 기능을 추가해본다.

read 모드에서 content 목록을 클릭하고, update 링크를 클릭하면 해당 content의 내용을 수정할 수 있게 기능을 추가한다.

우선 form 기능이 구현되어 있는 CreateContent 컴포넌트를 복사해서 새로운 UpdateContent 컴포넌트를 생성한다.

updateContent.js

 

UpdateContent 컴포넌트의 코드 수정은 잠시 뒤에 하고, App.js 에서 mode가 'update'로 변경되었을 때 동작을 추가한다.

App.js

그리고 이전 render() 내부의 코드를 깔끔하게 보이도록 getContent() 함수로 빼내준다.

App.js / getContent()

getContent() 함수는 _article을 반환하게끔 코드를 수정해준다.

App.js / return()

이전에 {_article}로 쓰던 102번 라인의 코드를 {this.getContent()}로 수정한다.

 

다시 update 모드일 때의 코드로 돌아와서 코드를 수정한다.

App.js / getContent()

'read' 모드일 때와 동일하게 앱에서 선택한 content의 id와 같은 id를 가지는 contents 배열의 값을 selected_content 변수로 정의한다.

그리고 UpdateContent 컴포넌트의 props인 data로 전달해준다.

 

이번에는 UpdateContent 컴포넌트의 코드를 수정한다.

updateContent.js

리액트의 value 속성을 사용해서 <input> 태그의 값을 props의 data.title로 초기화한다.

그런데 이 코드를 저장하고 앱을 확인하면 오류가 발생한다.

props 데이터는 읽기 전용이라 그대로 사용하면 안된다고 한다.

update 모드일 때의 form 요소에 내용을 수정하려고 해도 입력에 따른 변화가 아예 없는 것도 확인할 수 있다.

 

오류를 수정하기 위해 value 값으로 컴포넌트 안에서 가변적인 데이터를 state화 시켜줘야 한다.

updateContent.js

하지만 코드를 수정해도 오류가 발생한다.

state화 시켜도 근본적인 문제(읽기 전용인 데이터를 수정하려고 함)가 해결되지 않기 때문이다.

오류에 적혀있는대로 onChange를 작성해서 수정해주자.

updateContent.js

여기서 e.target.value는 이벤트의 타깃인 <inpute> 태그의 value 값을 뜻한다.

업데이트할 때마다 한글자씩 바뀌는 value 값들을 컴포넌트의 state 값에 바로 동기화키도록 코드를 작성했다.

이제 update 모드에서 form 요소에 내용을 수정해도 콘솔에 오류가 발생하지 않는다.

<textarea> 태그도 동일하게 value 속성과 onChange 속성을 추가한다.

updateContent.js

 

onChange 속성 값을 깔끔하게 함수로 수정해줄 수있다.

updateContent.js

[e.target.name]은 이벤트가 발생한 태그의 이름을 나타낸다. 대괄호가 없으면 e.target.name을 키값으로 검색하기 때문에 꼭 대괄호를 사용해줘야 한다. 자바스크립트 es6에 추가된 객체 리터럴 문법이다.

https://www.inflearn.com/questions/771416/%EC%84%A0%EC%83%9D%EB%8B%98-key-%EA%B0%92%EC%97%90-%EA%B4%84%ED%98%B8%ED%91%9C%EA%B8%B0%EB%B2%95-%EC%93%B0%EB%8A%94-%EC%9D%B4%EC%9C%A0%EA%B0%80-%EB%AD%94%EA%B0%80%EC%9A%94

 

선생님 key 값에 괄호표기법 쓰는 이유가 뭔가요? - 인프런 | 질문 & 답변

[사진]e.target.name에 []괄호 안에넣는데 e.target.name 자체가 string이잖아요 괄호표기법으로 안써도 위에서는 그냥 author: '' 이렇게 key갑: value 값 써줬는데 e.target.name도 console찍어보면 author라고 뜨는데

www.inflearn.com

 

inputFormHandler() 함수를 만들어도 .bind(this) 코드가 항상 붙어다니기 때문에 이 코드를 줄이기 위해

constructor에 inputFormHandler 프로퍼티를 만들어서 bind(this)를 묶은 inputFormHandler를 대입해준다.

updateContent.js

이렇게 코드를 깔끔하게 줄일 수 있다.

 

마지막으로 submit 버튼을 클릭했을 때 수정한 내용이 업데이트되도록 구현한다.

업데이트할 content를 식별할 변수가 필요하기 때문에 props로 받아온 data의 id를 식별자로 사용한다.

updateContent.js
updateContent.js

data의 id를 value로 가지는 <input> 태그를 hidden 속성으로 만들어준다.

이렇게 hidden 속성값을 가지는 <input> 태그는 사용자에게 보이지 않는다.

 

이 식별자 id를 onSubmit() 함수에 인자로 전달해준다.

updateContent.js

이전에는 이벤트 객체 e의 target에서 title과 desc의 값들을 찾아서 인자로 전달해줬는데, 코드를 수정하면서 state에 정보들이 담겨있기 때문에 "this.state.id"와 같이 코드를 수정한다.

 

App.js로 돌아가서 UpdateContent 컴포넌트의 onSubmit 함수를 수정해준다.

App.js

인자로 전달받은 _id와 contents의 id를 비교해서 같은 id를 가지는 content를 새로운 title과 desc로 업데이트하도록 코드를 추가한다.

여기서 사용한 Array.from() 또한 원본 배열을 수정하지 않고 배열 객체를 복사하는 메소드이다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/from

 

Array.from() - JavaScript | MDN

Array.from() 메서드는 유사 배열 객체(array-like object)나 반복 가능한 객체(iterable object)를 얕게 복사해 새로운Array 객체를 만듭니다.

developer.mozilla.org

 

앱에서 잘 동작하는지 확인한다.

submit 버튼 누르기 전
submit 버튼 누른 후
수정된 모습

 

추가로, submit 버튼을 클릭하고 바로 수정한 내용을 확인하고 싶다면 mode를 "read"로 변경해주기만 하면 된다.

App.js

create 모드일 때도 동일하게 submit 버튼을 클릭했을 때 mode를 "read"로 변경시키고 selected_content를 추가한 content의 id로 변경시켜주면 content를 추가하자마자 확인할 수 있다.


부스트코스의 강의 내용을 정리한 포스트입니다.

https://www.boostcourse.org/web231/lecture/1387441

 

웹 프론트엔드 시작하기 (리액트&리덕스)

부스트코스 무료 강의

www.boostcourse.org

BELATED ARTICLES

more