양식 제출처리, 컴포넌트 연결, 웹페이지 동적변환
양식을 제출하여 데이터 받기 및 state 끌어올리기를 통해 컴포넌트 연결하기
어제 만든 양식은 버튼 타입이 submit이어서 양식이 제출되면 새로운 페이지가 로드되는 동작이 나타나게 된다. 현재 만든 웹페이지에서는 그런 동작이 불필요하기에 이를 없애주는 처리를 해보았다.
위 코드는 form 자체에 연결된 이벤트 함수인데, 기본동작을 막기 위해 event 매개변수를 사용하여 preventDefault 메서드를 사용해주었다.
그리고 제출이 되면 받을 데이터에 대한 객체를 만들어주었다. itemNameChange, priceChange, dateChange는 어제 useState를 사용하며 정의한 상태 값이다. 또한, 이 객체는 양식데이터를 담고 있는 부모파일인 ExpenseUser 파일의 onUserFormData 함수의 값으로 설정해주었다. 양방향으로 공유하는 것이다. 이것을 state 끌어올리기라고 한다.
이렇게 부모요소에 값이 전달되면 제출이 완료된 것이므로 상태 값들을 빈 문자열로 변경해주도록 설정해주었다.
부모파일인 ExpenseUser 파일에서는 자식파일로부터 받은 양식 데이터를 받는 userFormDataHandler 함수를 만들고 데이터를 formData 매개변수에 받도록 했다. 함수 내에서는 userFormData 객체를 만들어 가져온 양식 데이터를 저장하고, 추가적으로 랜덤 아이디를 부여하도록 설정했다. 그리고 이 객체를 최종적으로 화면에 표출되는 App.js 파일의 onAddList 함수의 값으로 설정해주었다.
반환문에서 사용자 양식이 있는 자식파일에 onUserFormData라는 속성을 만들어서 위에서 만든 함수를 전달해주었다. 이 함수는 자식파일의 submitHandler 함수에서 실행된다.
웹페이지 동적으로 변환하기
어제까지 만든 웹페이지는 정적 페이지였다. 그래서 오늘 이 부분을 수정해주었다.
우선 useState 함수를 사용하여 기존에 App.js에 있던 지출예시(expensesDummy)를 기본값으로 하도록 했다. 그리고 상태 값인 expense와 상태값 변경 함수 setExpense를 정의해주었다. 참고로 이 지출예시는 함수 안에 있었는데 밖으로 빼주고 이름을 바꿔주었다.
addExpenseListHandler는 양식파일을 담고있는 ExpenseUser 파일에 연결된 함수이며, 사용자가 '리스트에 추가하기' 버튼을 누르면 제출되면서 이 함수가 실행된다. 함수에서는 ExpenseUser 파일에서 받은 userFormData를 newExpense 매개변수로 받도록 하고, 기존 지출리스트는 유지한 상태에서 새로운 값을 받기 위해 상태값 변경 함수를 실행하고 기존의 값들은 prevExpense에 저장하고, 새 값이 이전 값보다 앞에 표출되도록 설정했다. 이전 값은 스프레드 연산자를 사용하여 변경되지 않도록 설정했다.
App 파일의 반환문도 업데이트해주었는데, ExpenseUser 파일에는 onAddList 속성을 사용하여 함수를 전달해주었다. 지출예시의 데이터를 담은 파일에서 사용하는 item 속성도 기존의 지출예시를 직접적으로 값으로 받는 게 아니라, 위에서 새로 정의한 expense를 값으로 받도록 했다.
이 지출예시 데이터 파일도 동적코드로 변환해주었는데, 기존에 하드코딩되어있던 부분을 없애고, 부모로부터 받은 props.item에 map 메서드를 사용했다. 이 map 메서드는 기존 배열의 각 요소를 변환하여 새 배열을 만들게 되므로, 여기서는 props.item의 배열을 변환하게 된다. 총 4개의 객체가 들어있으므로 각각의 값으로 변환되는 것이다.
이를 위해 item 데이터를 expensesExample에 저장하도록 하고, ExpenseItem 파일을 불러와서 객체 내 각 요소에 대해 정의해주었다. 이렇게 하면 사용자가 새로 추가한 데이터에 대해서도 같은 방식으로 변환하게 된다.
위 코드들의 결과물로 위 이미지처럼 사용자가 form에 입력한 데이터가 기존 리스트의 상단에 표출된 걸 확인할 수 있다. 이 과정에서 임시적으로 추가했던 가격 옆에 있는 클릭 이벤트리스너를 삭제하고, itemName도 다시 앞에 props를 붙여주었다.
지출리스트에 적용할 필터 만들기
오늘은 지출리스트에 적용할 필터를 만들어주었는데, 각 연도별로 리스트를 볼 수 있는 환경을 제공하기 위해서 만들었다.
이를 위해 새로운 컴포넌트인 ExpenseListFilter를 만들었고, 반환문에 연도별 지출리스트라는 이름의 드롭다운메뉴를 만들어주었다. 여기서는 사용자가 2020년부터 2023년도까지 선택할 수 있도록 했다.
또, 각 연도를 선택하면 리스트가 변하도록 하기 위해 onChange 이벤트리스너를 만들어 filterChangeHandler 함수를 연결해주었다. 이 함수는 사용자가 선택한 연도를 받아 저장하기 위해 event 매개변수를 만들었고, 선택 값인 event.target.value를 slectedYear 상수에 저장해주었다.
그 이후에 부모 App.js로부터 받은 onFilterChange 함수가 실행되면서 이 함수의 값으로 사용자가 선택한 연도 값을 설정해주었다.
부모파일에서는 useState 함수를 불러와서 기본값으로 2023년이 표출되도록 하고, 상태 값과 상태값 변경 함수를 정의해주었다. 여기서 기본값으로 선택한 연도는 ExpenseListFilter 파일에 selected라는 이름으로 속성을 만들어 값을 selectedYear로 지정해주었다.
그리고 ExpenseListFilter 파일에 연결된 onFilterChange 함수는 사용자가 선택한 연도를 userYear 매개변수에 저장하도록 하고, 이를 상태값 변경 함수의 값으로 연결해주었다. 아직 리스트에 반영되지는 않지만, 콘솔에는 선택한 연도가 표출되고 있다.
