var은 중복선언이 가능하다. let은 중복선언이 불가능하다. 둘다 재할당은 가능(당연한 소리)
case1) var은 재할당, 중복선언 모두 가능하다. --> 이상한것..
var gender = 'female'
console.log(gender)
// 변수 재할당 가능
gender = 'none'
console.log(gender)
// 변수 중복 선언 가능
var gender = 'male'
console.log(gender)
case2) let은 재할당은 가능하나 중복선언이 불가하다. -> 당연한것..
let name = 'Mike'
console.log(name) // output: Mike
// 변수 재할당 가능
name = 'Heidy'
console.log(name) // output: Heidy
// 변수 중복선언 불가
let name = 'Sally' // output: Uncaught SyntaxError: Identifier 'name' has already been declared
case3) const 는 상수라서, 재할당 불가, 중복선언도 불가
// 원시값의 재할당
const name = 'kmj'
name = 'howdy' // output: Uncaught TypeError: Assignment to constant variable.
// 객체의 재할당
const name = {
eng: 'kmj',
}
name.eng = 'howdy'
console.log(name) // output: { eng: "howdy" }
var & let 호이스팅 관점에서의 차이점
자바스크립트 엔진은 선언문(변수선언, 함수선언)을 찾아내 먼저 실행한다 -> 호이스팅
var과 let은 둘다 호이스팅 된다.
하지만 var은 할당이 되지 않았을 때도, undefined라고 자체적으로 초기값을 넣어서 에러를 발생시키지 않는다.
let은 할당되지 않았을 경우, 초기값이 없다는 에러를 발생시킨다.
case1) a를 선언하지 않고 부르면 당연히 에러발생
console.log(a)
case2) a를 선언하고 부르면 당연히 잘 불려짐
var a = "apple"
console.log(a)
case3) a를 부르고, 선언하면? 에러는 안났는데, 할당이 안된것
-> 호이스팅 (선언+undefined라고 초기화)
console.log(a)
var a = "apple"
case4) 그럼 let으로 a 를 선언했을 경우는? 에러난다
console.log(a)
let a = "apple"
변수 뿐아니라 var, let, const, function, function*, class 의 키워드를 사용한 선언문은 모두 호이스팅 된다.
var & let 스코프 관점에서의 차이점
var은 함수만 지역스코프로 인정되어 지역변수로 처리된다.
let은 모든 브라켓표현식을 지역스코프로 인정하여 지역변수 처리한다.
case1) var는 function 브라켓(스코프) 안에서는 지역변수로 작동한다.
var a = 1; // 전역변수
function test() {
var b = 2; // 지역변수
}
console.log(a)
console.log(b) // 함수브라켓은 지역변수로 작동하여, 밖에서 호출시 에러
case2) function 이 아닌 다른 브라켓(스코프) , for, while, if, switch...등 안에서는 지역변수로 처리되지 않는다.
var a = 1;
while(true){
var b = 5;
break
}
console.log(a)
console.log(b)
case3) let은 모든 브라켓(스코프)안에서 선언된 변수들은 모두 지역변수로 처리한다
var a = 1;
while(true){
let b = 5;
break
}
console.log(a)
console.log(b) // 지역스코프 밖에서 호출시 에러
부모 컴포넌트에서 전달받은 initialDate, control, watch 를 받고있다.
1. Controller 는 name을 갖게될 하나하나의 필드값에 적용해야한다. 그러므로 부모컴포넌트에서가 아닌 자식 컴포넌트에 지정을 해야한다.
부모 컴포넌트에서는 react-hook-form과 mui를 연결해줄 control 값만 받아오고, Controller는 자식컴포넌트에서 import 하여 startDate를 위해 감싸주고, endDate를 위해 감싸주는 것처럼 각각의 필드값을 각각 감싸주는 것이다.
2. initialDate는 defaultValue를 지정하기 위해서 부모 컴포넌트에서 받아주었다.
이는 다른 부모 컴포넌트들에서는 다른 initialDate를 사용하기 때문에 자식 컴포넌트에 직접 defaultValue에 적지 않았다. 무조건 new Date() 라는 값을 defaultValue 로 사용할 거라면 initialDate를 전달받지 말고 자식 컴포넌트에 바로 적어주어도 된다.
3. 부모로 부터 전달받은 control을 console.log로 찍어봤다.
그냥 react-hook-form 과 연결하기 위한 여러가지 값들이라고 생각하고 넘어가자...ㅎ
4. 이제 watch 에 대해서 알아보자.
watch는 react-hook-form 에서 제공한다.
말그대로 해당 필드의 값을 계속 지켜보겠다는 것 이다.
watch("startDatetime") 을 console.log로 찍어보았다.
시작일 값이 변경될 때마다 변경된 Date 값을 찍어준다.
우리의 dateRangePicker 는 시작일과, 종료일이 서로 연관되어있다. 기간의 개념으로, 종료일은 시작일보다 빠를 수 없다.
이에 대한 설정 값이
시작일 의 경우
종료일의 경우
여기서 기간에 대한 개념을 구현하기 위해서는 서로 다른 필드값 (startDatetime / endDatetime) 을 참조해야하는 것이다.
controller를 import 한 뒤 , 원하는 UI 컴포넌트를 <Controller> 컴포넌트로 감싸주면 된다.
여기서 핵심적으로 다른 부분은 바로 onChange 속성을 사용하는 것이다.
우선 1편과 동일하게 전달해주는 속성들에 대해서 간략하게 정리해보자
name : 역시 form 제출시 key 값으로 사용될 값이다. 이 경우 게시글을 공개할껀지, 비공개로 할 것인지를 정하는 shareStatus라는 키값으로 표현했다. 서버로 제출시 "shareStatus" : false 이런식으로 제출될 예정!
control : react-hook-form과 material-UI를 연결해주는 용도라고 생각하고 넘어가자
defaultValue : 역시 1편에서 설명했듯이, 지정하지 않으면 쓸 데없는 warning이 발생한다.
index.js:1 Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components
render : 내가 쓰고 싶은 UI의 컴포넌트를 적어주면 되는 부분이다.
field : form에 제출하는 value와 관련된 내용을 이어준다? 라고 생각해보자
일단, 나의 경우 shareStatus 값에 따라서 위의 타이틀이 공개 <-> 비공개 토클이 되어야 해서 위와 같이 삼항연산자로 표현해 주었다 상단의 타이틀 토글
ToggleButton 컴포넌트를 랜더링해준다. ToggleButton 컴포넌트의 경우 mui에서 제공하는 도큐먼트에 따르면,
value = 'check' 라는 props를 통해서 checkbox 처럼 true/false 값으로 사용할 수 있다.
selected 속성은 field.value를 통해서 react-hook-form이 읽어갈 value 값과 연결을 해준다.
onChange 속성은 mui에서 제공하는 props인데, 이제 이를 react-hook-form 의 onChange와 연결을 해주어야 한다. 그 방법은 위에 code와 같다. field 객체 안의 onChange 함수를 실행시키면서, field.value의 값을 ! 로 토글 시키는 것이다 (true<->false)
다음 게시글에서는 <TextField> , <ToggleButton> 처럼 단일 컴포넌트를 받아서 쓰는 것이 아닌, 여러가지 컴포넌트들을 조합하여 커스텀한 컴포넌트 그룹을 react-hook-form 과 연결하는 방법에 대해 정리해 보려 한다.
name : react-hook-form이 작성된 폼의 값들을 모아서 제출할 때, key 값으로 사용할 값이다. 유니크한 값으로 지정하도록 한다.
control : 상단의 useForm() 에서 선언한 control 인데, 간단하게 react-hook-form과 mui를 이어주는 용도라고 생각하자
defaultValue : 말 그대로 초기값인데, 없다면 빈스트링이라도 지정해두자. 지정하지 않으면 다음과 같은 warning 이 발생한다
index.js:1 Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components
render : 이제 내가 쓰고 싶은 UI 컴포넌트를 어떤식으로 렌더링 하겠다고, react-hook-form 에게 알려주는 부분이다다. 이 부분에서 원하는 컴포넌트를 (TextField)를 사용하면된다. TextField 컴포넌트 내부의 props들은 그냥 material-UI에서 제공하는 내용을 원하는대로 가져다 쓰면된다.
error : mui 에서 기본적으로 제공하는 prop이지만 이를 react-hook-form에서 제공하는 validation 과 errors를 받아서 사용할 수 있다.
helperText : 역시 react-hook-form에서 던져주는 에러메시지를 받아서 사용할 수 있다. (기본적으로 영문 메시지가 뜨는데, 아래의 경우는 yup이라는 validation check용 라이브러리를 사용하여 에러메시지를 지정해준 경우이다.)
TextField의 경우 onChange 등 별도로 지정해 줄게 따로 없어서 간단하다.
다음 게시물(2)에서는 onChange 속성을 사용하는 ToggleButton에 대해서 알아보려한다.