components폴더안에 habitAddForm.jsx 파일을 만든 후에 rcc를 이용해서 기본골격을 만든 다음에
habitAddForm은 추가해주는 form이기 때문에 div대신에 form을 이용한다.
클래스 이름은 add-form으로 해주고 input은 type은 text로 해주고, 클래스이름을 add-input으로 지정해준다.
placeholder도 넣어주고 (텍스트가 미리 보여질 수 있도록) 마지막으로 사용자가 버튼을 눌러야 하니까 버튼도 지정해준다.
목록 만들기전에 habits에다가 render()부분에 텅텅 빈 컨테이너 안에 ul을 추가해주고 위에다가 HabitAddForm을 추가해주면 import 되어진다.
그러면 아래와 같이UI가 표기되어진다.
이제 Add를 누르면 UI에다가 추가가 되도록 설정을 해주면 되는데 habitaddform파일에다가 사용자가 버튼을 누르면
onSubmit하는 함수를 호출할 것이다. 그래서 클래스에는 onSubmit이라는 멤버변수가 있는데 이벤트를 항상 받는 형식을 나타내어준다. 로그를 해서 클릭해보면 페이지가 리로딩된다.
기본적으로 submit이 발생하면 페이지가 새로고침 되거나 다른 페이지로 가는 걸 예상해서 그렇다.
그러므로 preventDefault라는 것을 이용해서 browser의 기본 기능을 취소해줘보자. 그러면 더이상 새로고침이 되지 않는다.
사용자가 입력한 input에 입력된 이름을 이용해서 새로운 습관을 만들어보면 input에 입력된 데이터를 알아와야 하는데 DOM에서는 기본적으로 querySelector을 이용해서 클래스 이용해서 input 필드를 받아온 다음에 input에 있는 value를 알아왔지만
리액트에서는 Ref 라는 것을 이용하는데 리액트에서는 DOM요소를 직접적으로 쓰지 않기 때문에 리액트에서 다른 리액트의 요소에 접근하고 싶다면 Ref를 쓰면 된다.
먼저 멤버변수를 입력해주는데 사용자가 input에 접근해야 되기 때문엡 inputRef라고 이름을 적어주고 리액트에 있는 createRef()라는 함수를 호출하면 Ref라는 오브젝트가 생기고, 이것을 원하는 요소에 Ref에다가 전달을 해주면 된다.
그러면 컴포넌트가 브라우저에 표기가 되면 input이라는 요소가 inputRef와 연결이 된다. 그래서 요소에 접근해서 해당하는 데이터를 읽어올 수가 있다. 클래스에 있는 inputRef를 참고해야 하니까 this를 써준다.
console.log를 이용해서 this.inputRef안에 있는 그리고 Ref안에는 현재 있는 요소의 value를 읽어 올거다.
createRef는 사용자가 브라우저에서 이용할 때 DOM 요소에 접근해서 그 요소에 value나 클릭 이벤트나 이러한 것을 들록 했던 것처럼 리액트는 바로 DOM 요소에 접근하지 않고 필요할 때는 이렇게 리액트에서 제공하는 createRef라는 것을 이용해서 멤버변수를 정의한 다음에 원하는 리액트 컴포넌트에 ref로 연결하면 된다.
habit의 이름은 inputRef에 있는 value를 받아오고 이름이 비어있지 않다면 props에 전달된 onAdd라는 함수에 이름을 전달해준다.
onAdd라는 것이 아직 없기 때문에 habits.jsx에다가 onAdd라고 똑같이 해주면 된다.
hadleAdd는 habit에 이름이 오면 this.props.onAdd에 동일하게 name을 전달한다.
this.props.handleDelete을 이용해서 바로 호출할 수도 있다. 그러면 굳이 멤버변수를 일일히 작성하지 않아도 된다.
render 함수가 호출 될 때마다 Arrow function이 계속 만들어 지긴 하지만,(메모리에 영향이 간다.) 그래도 크게 차지를 하지 않는다. 하지만 이렇게 쓸 수 있는 경우가 있고 쓰면 안되는 경우가 있는데 리액트 훅을 할때 다시 자세히 배우도록 하자.
그리고 app.jsx에 최종적으로 앱이 이런 state를 다 가지고 있으니까 habit에는 onAdd도 추가해주고 handleAdd도 추가해준다. handleAdd은 이름을 받아서 그 이름에 맞는 새로운 습관을 state에 추가해 주면 된다.
새로운 것이 추가되면 항상 복사해 와야 하기 때문에 habits라는 새로운 배열을 만들 것인데, 기존 state에 있는 habits을 하나씩 spread operator를 이용해서 habits에 있는 아이템들을 하나씩 새로운 배열에 복사해 오는것이다.
각각에 있는 걸 복사해 온다음, 주어진 이름을 이용해서 새로운 habit도 만들어야 한다. 그래서 아이디는 고유한 것들을 써야 한다.(새로 만드는 것은 고유한 아이디를 쓴다.)
간단하게 Date.now()를 이용해서 현재 날짜와 시간을 합해서 초까지 합해서 만들어 준다. 이걸로 고유한 것들을 만들고 이름은 주어진 이름을 이용하고 count: 0, 동일한 이름일 때는 생략이 가능하므로 생략해준다.
다음에 this.setState 이용해서 전체적으로 업데이트 해 주면 된다.
추가된 다음 input에 있는 것들이 초기화되면 깔끔하니까 habutAddForm에다가 this에 inputRef.current.value를 빈값으로 해주면 된다. 텅텅 빈 문자열 이런 식으로 추가해줘도 되고
form에서 나오는 걸 초기화하고 싶으면 formRef에 그대로 복사해서 formRef는 this.formRef를 연결해 준 다음에
formRef에 있는 current.reset을 호출 해줘도 된다.
이제 habit에서 리셋 버튼을 추가할 건데, reset은 habits안에 포함된 것으로, 재사용될 가능성이 거의 없다.
그래서 걍 태그를 사용해서 버튼이 반복적으로 사용될 때 다시 컴포넌트로 따로 빼서 만들어도 되고 그냥
버튼이라는 태그를 이용해서 habits-reset이라는 클래스를 지정해주고 안에는 reset all 글자를 해주고 onClick이
발생하면 this안에 있는 props.onReset을 연결해준다.
다음에 app에 와서 handleReset은 아무것도 받지 않고 onReset을 연결해준다. 다음 count를 돌면서 0으로 만들어 주면 되니까 새로운 배열을 만들고 habits을 돌면서 새롭게 데이터를 만들거기 때문에 map을 이용해주고 habit을 받아서 habit의 count를 0으로 만든 다음에 동일한 habit을 return할 것이다. 즉 habit 돌면서 새로운 배열로 만든다. 다음 this.setState를 이용해서 habits를 넣어준다.
CSS도 간단하게 habit밑에다가 reset을 이쁘게 지정해주고 add-input도 navbar밑에다가 지정해준다.
스타일링이나 구현하는게 조금 구리긴 하지만 클론코딩을 함으로써 리액트를 공부하기에 좋은 예제 프로젝트가 된거같
다. 다음에는 성능 분석하는거와 리액트 훅으로 어떻게 변환할 수 있는지 PureComponent와 memo 이것들을 공부해보자
<출처 : DreamCoding 리액트 개념 정리+유튜브 클론코딩: ellie>
참고: https://academy.dream-coding.com/courses/react-basic
리액트 강의 (유튜브 클론 코딩 + 실시간 전송 명함 카드 만들기 웹앱 만들기)
리액트 전반적인 개념 설명과 (클래스 컴포넌트와 함수 컴포넌트 그리고 리액트 훅까지) 실전 유튜브 클론 코딩 프로젝트. Firebas의 실시간 데이터베이스를 이용해 멋진 명함 카드 만들기 웹 어
academy.dream-coding.com
'React > HabitTracker' 카테고리의 다른 글
PureComponent정리와 차이점 최종 정리 (0) | 2021.07.31 |
---|---|
PureComponent정리와 차이점 이해(성능 분석) (0) | 2021.07.31 |
App 컴포넌트 만들어 보기(Navbar 컴포넌트 만들기) (0) | 2021.07.31 |
이벤트 처리 하기(업데이트 함수들 구현하기) (0) | 2021.07.31 |
이벤트 처리 하기(part1 . 골격 만들기) (0) | 2021.07.29 |