본문 바로가기
  • Seizure But Okay Developer
FrontEnd/React 관련자료

리액트 기본 과정 정리 - 8 [배열 다루기 (2) 제거와 수정]

by Sky_Developer 2019. 12. 12.
이 글은 Velopert 님의 인프런 - 누구든지 하는 리액트 강의 를 참고하여 작성한 글입니다. 혹시 저작권 상의 문제가 발생할시에 내리도록 하겠습니다.

개요

리액트 강의를 듣고 기본 개념을 정리하고 기억하기 위해 작성하였습니다. 공부하시는 다른 분들께 도움이 되었으면 합니다. 이번 글에서는 강의에서 중요하다고 생각되는 부분만 담았으니 참고 부탁드립니다.

 

데이터 제거

지난 섹션에서 배열에 데이터를 추가하는 방법과 배열 내부의 내용들을 화면에 보여주는 기능을 구현하였습니다. 이번에는 배열 내부의 데이터를 제거하는 방법과 수정하는 방법을 알아보겠습니다. 이 작업이 어려운 것은 아니지만 불변성을 유지하면서 작업을 처리해줘야 하기 때문에 기존에 하던 것과는 조금 다를 수 있습니다.

 

기존의 배열 데이터를 건들지 않으면서(불변성을 유지하면서) 데이터를 제거하기 위해선 여러가지 방법이 있을 수 있는데, 그 중에서 자바스크립트의 내장함수인 slice 혹은 filter 메소드를 사용할 것입니다.

 

다음 코드를 보세요.

 

App.js

UI 적으로 봤을 때 X 버튼을 누르면 사라지게 할 것입니다. 구체적으론 해당 컴포넌트의 id  값이 넘어오고, 그 컴포넌트 id 값을 제외한 새로운 배열을 렌더링해서 사라져 보이게 할 것입니다.

 

handleRemove 함수를 만들고 인자로 id값을 받습니다. 그리고 비구조화 할당을 통해 information이란 레퍼런스를 따로 만들어줍니다. 그리고 setState 함수 내에 filter 함수를 통해서 인자로 받은 id 값이 아닌 것들만 새로 배열로 만들어줍니다. 이 함수를 PhoneInfoList 에게 전달해줍니다. 이제 PhoneInfoList 컴포넌트를 보겠습니다.

 

PhoneInfoList.js

PhoneInfoList 에선 props로 받아온 onRemove를 다시 PhoneInfo 에게 그대로 전달해줄 것입니다. 먼저 비구조화 할당 문법을 통해 onRemove 를 레퍼런스로 만들어 줍니다. 그리고 이를 PhoneInfo 컴포넌트에게 onRemove 라는 이름으로 전달해줍니다.

 

이제 PhoneInfo 컴포넌트를 보겠습니다.

 

PhoneInfo.js

여기서도 handleRemove 함수를 또 구현해줍니다. 그리고 여기서 info, handleRemove 를 레퍼런스로 만들고 handleRemove에 info의 id 값을 인자로 넘겨줍니다.

 

그리고 하단에 삭제 버튼을 만들어서 버튼의 onClick 이벤트와 handleRemove 함수와 연결해줍니다.

 

handleRemove 함수를 다음과 같은 방식으로도 구현할 수 있습니다. render 함수내에서 id와 onRemove 를 레퍼런스로 만들어서 이 값들을 가지고 처리를 하는 것입니다.

 

 

데이터 수정

이번에는 데이터 수정을 해보겠습니다. 이 때에는 자바스크립트의 내장 함수 중 slice 혹은 map 함수를 사용할 수 있습니다. 수정할때도 마찬가지로 불변성을 지켜줘야 합니다. 기존의 배열과, 그리고 그 내부에 있는 객체를 절대로 직접적으로 수정하면 안됩니다.

 

우리는 handleUpdate 라는 함수를 만들어 id와 data라는 파라미터를 받아서 필요한 정보를 업데이트 해줄 것입니다.

다음 코드를 보세요.

 

App.js

id 는 어떤 컴포넌트를 바꿀 것인지를 알 수 있는 값이며 data는 어떻게 바꿀 지에 대한 정보입니다.

먼저 information을 비구조화 할당으로 레퍼런스를 만듭니다. 그리고 setState 함수 내에서 information 배열을 map 함수로 변환을 해줍니다. 만약 information 배열 내의 요소의 id 와 파라미터로 가져온 id 가 일치한다면 id 값은 그대로 두고 새로운 name과 phone 값 (data)이 들어가지게 합니다. 만약 id 가 다르면 요소 자체를 그대로 반환합니다.

 

이제 이 함수를 PhoneInfoList 에 onUpdate라는 prosp로 전달합니다.

 

 

PhoneInfoList.js

그리고 PhoneInfoList 에선 데이터를 컴포넌트로 렌더링하는 과정에서 받은 onUpdate 함수를 다시 PhoneInfo 컴포넌트로 넘겨줍니다.

 

이제 PhoneInfo 컴포넌트를 보겠습니다. 하단에 조금 짤린 부분은 닫는 태그들이라 중요한 부분은 아니어서 추가사진을 첨부하지 않았습니다.

 

PhoneInfo.js

PhoneInfo 에선 수정 모드를 새로 만들어 줍니다. state를 새로 만들고 여기에 editing 값을 false로 우선 설정합니다. 그리고 이 editing 값을 반전시켜주는 handleToggleEdit 이라는 함수를 만듭니다.

 

handleToggleEdit 함수를 선언하고 setState 함수를 통해서 editing 값을 반전해줍니다. 그리고 수정 버튼을 만들어 onClick 이벤트에 handleToggleEdit 함수를 연결해줍니다. 추가적으로 버튼 내용이 자연스럽게 나오게 하기 위해 editing이 true 이면 '적용' 이 뜨도록 하고 false 이면 '수정' 버튼이 보이도록 합니다.

 

그리고 editing 값이 true가 되면 input 폼이 보이게 할 것입니다. 먼저 상단에서 Fragment 를 추가로 import 하고, editing 레퍼런스를 만듭니다. Fragment 는 JSX 내에서 태그를 감싸줘야 하는데 추가적인 div 태그를 만들고 싶지 않을 때 사용합니다.

 

그래서 editing 이 true 이면 두 개의 input 태그가 보이게 합니다. 이 input 태그들은 각각 이름과 폰 번호 데이터가 입력됩니다.

 

여기까지만 하면 수정을 눌렀을 때 기존 내용이 input 태그에 기본값으로 뜨지도 않고, 새로 적은 내용이 반영되지도 않습니다. 전자를 처리하기 위해 state 에서 input 값을 관리해주어야 합니다.

 

state 에서 name, phone 값을 추가로 만들어 줍니다.

 

그리고 handleChange 함수를 만들고 기존에 input 태그의 값과 이름을 이벤트 객체로 받아서 computed property names 로 처리해줬던 것처럼 똑같이 처리해줍니다. 그리고 이 함수를 각 input 태그의 onChange 이벤트와 연결해줍니다. name 도 설정을 해주고 value도 state로 부터 해당하는 값을 받아 설정해줍니다. 이 state 값과 관련해 추가적인 코드를 작성해야 하는데요.

 

handleToggleEdit 함수로 editing 값이 반전될 때(수정 버튼을 누를 때), 기존 컴포넌트에 적혀 있던 내용이 기본 값으로 오도록 해야 합니다. 그래서 추가적인 로직을 작성해주어야 하는데 다음과 같습니다.

 

  • editing 값이 true -> false 로 바뀔 때
    • props 로 전달받았던 onUpdate 함수를 사용해서 업데이트를 하겠다고 부모 컴포넌트에게 알려줌
  • editing 값이 false -> true 로 바뀔 때
    • props의 info 안에 있는 name, phone 값을 state에 넣어주는 작업을 해줌

일단 비구조화할당을 통해 info 값과 onUpdate 값에 대한 레퍼런스를 만듭니다. 만약 현재 editing 값이 true 일 때 onUpdate 함수에 첫 번째 인자로 어떤 컴포넌트인지 알려주는 info의 id 와 두 번째 인자로 어떻게 바꿀 것인지에 대한 정보(name, phone) 를 넘겨줍니다.

 

만약 editing 값이 false 라면 setState를 통해서 name는 info의 name, phone은 info의 phone으로 설정을 해줍니다.

 

여기까지 코드를 작성하고 실행하면 수정 버튼을 눌렀을 때 기본값이 뜨고, 또 값을 변경 후 적용을 했을 때 제대로 바뀌는 것을 확인할 수 있습니다.

 

이제 리액트 state 에 있는 배열 안에 있는 값을 삭제하고, 수정하는 방법을 알아보았습니다. 작업을 하면서 왜 배열과 객체값을 직접 수정하면 안되고 불변성 유지를 하면서 데이터를 새로 생성하는 방식으로 교체해줘야 하는지 의문이 들 수 있습니다. 이와 관련해서는 다음 글에서 불변성을 유지하는 이유에 대해 알아보겠습니다.

 

댓글