저번 시간까지 이 컴포넌트를 추가하고
여기에 값을 작성할 수 있도록 했습니다
이번 시간에는 저장을 눌렀을 때 이 값들을 모아서
유효성을 확인하겠습니다
만약 유효하지 않은 값이라면
예를 들면 지금 몇 가지 칸이 비어있는데
이럴 경우 에러 메시지를 띄우겠습니다
반대로 모든 입력 창에 올바른 정보가 입력되었다면
저장을 하여 새로운 프로젝트로 추가하여
옆에 사이드바에도 추가하겠습니다
성공 사례부터 시작하겠습니다
이 New Project 컴포넌트에
입력 창에 작성된 데이터를
모을 수 있는 방법이 필요합니다
한 가지 방법은
Change 이벤트를 받아서
키를 입력할 때마다 상태를 업데이트해서
입력된 값을 저장하는 것입니다
이전 강의에서 언급했던
접근 방식입니다
하지만 여기서는 이 값들을
저장 버튼을 눌렀을 때만 읽고
그 외의 상태를 추가 및 관리하지 않겠습니다
그러므로 여기에는 참조(ref)를 사용하겠습니다
참조를 사용하면 HTML 요소와 연결하고
그 요소들과 상호 작용할 수 있습니다
예를 들어 한 입력값을 가져오는 것입니다
먼저 리액트에서 useRef를 가져옵니다
여기엔 제목에 대해 titleRef를 만들겠습니다
혹은 그냥 title로 해도 됩니다
다음으로 상세 설명에 대한 description 속성
그리고 마감일에 대한 due date 속성입니다
세 가지 입력값에 대한 세 가지 참조입니다
여기서 중요한 부분은
여기 이 입력값은 커스텀 컴포넌트로
빌트인된 것이 아닙니다
그렇기 때문에
첫 번째 입력값의 참조를 이렇게 설정하면
작동하지 않을 것입니다
이렇게 하면 참조를 아래의 입력 요소에 설정할 수 없고
이 요소에 접근할 수 없게 됩니다
접근을 위해서는
그 커스텀 입력 컴포넌트 파일에서 뭔가를 바꿔야 합니다
새로 들어오는 참조를 전달하여
여기서 쓸 수 있게 하겠습니다
그렇게 해야 이 크로스 컴포넌트(cross-component) 참조 연결 구조가 완성됩니다
리액트에서 forwardRef를 가져오겠습니다
여기에서 새로 들어오는 참조를 내보내게 됩니다
또 이미 배우신 대로
이 컴포넌트 함수를 forwarRef 로 감싸서
변수나 상수로 저장하겠습니다
그리고 이렇게 표준(default)으로 내보내겠습니다
이렇게 하여 이 컴포넌트 함수를 감싸고
이 함수도 감싸서
새로운 매개변수를 얻습니다
속성 다음에 오는 매개변수로
정확히 말하면 이 속성 매개변수입니다
추가된 매개변수로
문자 영역(textarea)와 입력값에 접근할 수 있으며
여기에 모든 내장 요소에 있는
특수한 참조 속성을 추가하겠습니다
그리고 이것을 새로 들어오는 참조와 동일하게 설정하겠습니다
이렇게 하시면 됩니다
그리고 입력값에도 똑같이 합니다
문자 영역의 속성에 따라서
둘 중 하나가 렌더링이 되기 때문입니다
그렇게 하면
이 참조 속성을 커스텀 요소에 설정하고
전달해서
커스텀 요소 안에서 사용이 가능하게 됩니다
그에 대한 작업을 완료했습니다
이제 다른 입력값에도 동일한 작업을 해야 합니다
여기 상세 설명 입력값과
그리고 여기 마감일 입력에도 동일합니다
그렇게 하면 여기에 모든 참조를 설정하고
이 참조를 가지고
handleSave라는 함수를 만들겠습니다
이 함수는 저장 버튼과 연결되어 있습니다
여기서는 읽기 편하게
줄을 나누겠습니다
그리고 onClick 속성을 추가하여 handleSave로 가리키겠습니다
그러면 이 handleSave는
이 버튼이 클릭되었을 때 실행됩니다
이제 handleSave 안에는
입력된 제목을 불러올 수 있으므로
이 title 속성을 불러오고
그리고 여러분이 배우셨던 current 속성을 사용하겠습니다
참조 작업을 할 때는 항상 이런 식으로 해야 합니다
그리고 이것은 입력값이나 문자 영역을
참조해야 하고
두 요소 모두 값이기 때문에
.value 로 접근하여 입력된 값을 가져올 수 있습니다
같은 작업을 상세 설명에도 반복하겠습니다
Description 참조를 사용하겠습니다
그리고 당연히 마감일에도
DueDate 속성을 사용하여 반복합니다
유효성 검사도 추가하겠지만 이것은
이 모달은 유효하지 않은 값을 받을 때 작업하고
지금은 무조건 유효한 값이 들어온다고
가정하겠습니다
이제 이 모든 데이터를
앱 컴포넌트로 전달하겠습니다
이 컴포넌트에서 모든 프로젝트를 관리하고
새로운 프로젝트도 생성하기 때문입니다
그 다음 사이드바로 전달할
수도 있습니다
그래서 이 상태는 앱 컴포넌트 쪽으로 끌어올려야 하는데
앱 컴포넌트에서만
NewProject 컴포넌트에 접근이 가능하기 때문입니다
여기서 데이터가 만들어지고
상태 변화도 실행됩니다
ProjectsSidebar 컴포넌트에서는
상태 데이터가 나중에 필요할것입니다
그래서 여기 앱 컴포넌트에서
새로운 함수를 추가하여
handleAddProject 라고 칭하겠습니다
이 함수에서 프로젝트 추가 작업을 시작해서
여기서 끝내게 됩니다
그리고 이 함수에서
다시 setProjectState를 불러와야 합니다
이 함수 양식을 사용하면
기존 상태 위에 업데이트를 하고
이전의 상태도 그대로 저장할 수 있습니다
여기에 새로운 객체를 추가하겠습니다
이전의 상태를 펼치는 것으로 시작해서
기존의 데이터가
새로운 return 객체에 복제되게 하겠습니다
그 다음 프로젝트의 배열을 업데이트하겠습니다
배열을 업데이트하면서
기존의 프로젝트를 잃고 싶지 않기 때문에
먼저 이전의 프로젝트를 스프레드 연산자를 사용하여
이 배열 안으로 모두 복사하겠습니다
그리고 마지막 요소로는
추가될 새로운 프로젝트를 넣겠습니다
그럼 여기에 추가한 newProject가
새로운 객체가 됩니다
그리고 마지막엔 제목과 상세 내용
그리고 마감일 속성을 포함시키겠습니다
조금 더 단순화하려면
프로젝트 데이터를
매개변수로서 받되 그 위치가
이 함수가 호출되는 곳의 되게 하겠습니다
그리고 프로젝트 데이터는
제목, 상세 내용, 마감일 속성을 가지고 있는 객체로 받겠습니다
그러니 이 프로젝트 데이터를 여기에 펼치고
ID 를 추가하겠습니다
이건 나중에
프로젝트를 선택할 때 유용할 것입니다
이 ID는 여기서 생성되는데
Math.random을 불러와 생성하겠습니다
이는 자바스크립트에 내장된 함수인데
완벽한 ID를 주지는 않습니다
이론적상 같은 숫자가 두 번 나올 수 있기 때문입니다
하지만 이 연습 프로젝트에서는 이 정도면 충분합니다
이제 이것으로 새로운 프로젝트를 만들고
이 NewProject를
프로젝트 배열에 추가하겠습니다
이제 handleAddProject가
NewProject 컴포넌트에서 안에서 호출됩니다
이 handleSave 메소드(method)를 가지고 있고
여기서 모든 입력값을 가지고 있고
그리고 당연히 속성을 사용합니다
예를들면 여기서 onAdd 라는 속성을 추가할 수 있는데
이름은 언제나 임의로 지으시면 됩니다
그것을 handleSave안의 함수로 불러와서
객채를 인수로 보내려고 합니다
제목 속성을 가진 객체에는
입력된 제목이 있고
상세 내용 속성엔
입력된 상세 내용이 있고
그리고 마감일 속성엔 마감일에 대한 내용이 있습니다
이 구조의 객체는
앱 컴포넌트에서 보는 내용입니다
그리고 onAdd로 넘기는 이 객체는
여기 handleAddProject에서
인수로, 혹은 매개변수로 받게 됩니다
이제 handleAddProjects는
NewProject 컴포넌트에 새로 추가된
onAdd의 값이 됩니다
여기에 handleAddProject 함수를 넣겠습니다
그렇게 하면 연결 구조가 확립되고
이 projectsState는 업데이트가 되었을 것입니다
확인하기 위해
임시로 console.log를
컴포넌트에 추가하겠습니다
위치는 앱 컴포넌트 함수입니다
여기에 projectsState를 기록해서
위에 있는 프로젝트 목록이
바뀌는지 확인하겠습니다
우선 지금은 이걸 저장하고 새로고침하여
로그를 열면
아직은 빈 배열입니다
이제 새 프로젝트 만들기를 누르고
앱 컴포넌트가 업데이트 되었기때문에
빈 배열이 하나 더 생깁니다
여기에 '테스트'와 '이것은 테스트입니다' 를 적고
마감일은 오늘로 하겠습니다
데이트 피커(Datepicker)로 설정되어 있는지는
조금 있다가 확인해 보겠습니다
우선 저장을 누르면
데이터가 포함된입력
프로젝트 배열을 볼 수있습니다
여기 제가 방금 입력한 데이터가 있죠
즉 이 연결구조는 성공입니다
혹시 여기에 왜
앱 컴포넌트가 실행될 때마다
두 가지를 반환하는지 궁금하시다면
그것은 엄격모드(strict mode)가 활성화되어 있기 때문입니다
이전에 배우셨듯이
엄격모드에서는 컴포넌트 함수들이 두 번 실행됩니다
이제는
이 부분이 데이트 피커(Datepicker)가 되도록 하겠습니다
좀 더 정확한 데이터를 위해서입니다
그렇다면 NewProject 컴포넌트로 돌아가서
이 입력값 유형을 date로 설정합니다
이것은 리액트에 내장된 유형입니다
조금의 완성도를 위하여 이 첫 번째 입력값도
Text로 설정하겠습니다
이것을 저장하면
여기 데이트 피커 설정이 생겼기에
정확한 날짜를 고를 수 있습니다
이걸 저장하면
여기에서 새로운 프로젝트가 생긴 것을 볼 수있고
그리고 여기 정확한 날짜가 생겼습니다
이 성공 업데이트는 성공이었습니다
다음 시간에는
추가된 프로젝트들이 사이드바에 나오게 할 것입니다
그리고 저장을 누르면
이 컴포넌트가 닫히게 하겠습니다