class는 객체이자 물건 만드는 설명서입니다.
class안에는 함수와 변수를 넣을 수 있습니다. 이 변수와 함수를 조합해 붕어빵과 몬스터를 만드는 방법을 적어둘 수 있습니다.
그리고 붕어빵과 몬스터를 만들고 싶다면 new 붕어빵() 으로 만들어 줍니다.
만들어진 붕어빵과 몬스터는 객체 또는 인스턴스라고 부릅니다.
클래스에서 함수와 변수를 사용할때는 function, let, const를 붙이지 않습니다.
class {
// class에서의 함수 작성
sayHi() {
console.log("안녕하세요")
}
// class에서의 변수 작성
sayHi = "안녕하세요"
}
클래스에서 만들어진 함수를 메소드라고 부릅니다.
클래서에서는 공통 기능을 extends를 통해 상속해줄 수 있습니다.
//지상 몬스터와 공중 몬스터 만들기
// 공통 기능
basicFunc {
hp = 100
attack() {
console.log("공격을 시도했습니다.")
}
}
// 지상몬스터의 피하기
groundMonster extends basicFunc {
avoid() {
console.log("지상에서 뛰어서 피했습니다.")
}
}
// 공중몬스터의 피하기
flyMonster extends basicFunc {
avoid() {
console.log("공중으로 날아 피했습니다.")
}
}
import { component } from 'react'
export default class ClassCounterPage extends Component {
// class 변수의 선언 방식
state = {
count : 0,
}
// class에서의 함수 사용방식
onClickCounter = () => {
console.log(this.state.conut)
this.setState(((prev)) => ({
count : this.state.count +1 // this.state.count == prev.count
}))
}
// 화면 그리는 부분
render() {
return (
<div>
// this는 class 자기자신을 뜻합니다.
<div>현재 카운트 : {this.state.count}</div>
// 직접 바인딩 하실때는 onClick={this.onClickCounter.bind(this)} 라고 적어주셔야 합니다.
<button onClick={this.onClickCounter}>카운트 올리기</button>
</div>
)
}
}
this는 어디서 실행하냐에 따라서 변화하는 이슈가 있습니다. 즉, 실행하는 주체에 따라서 this가 다르게 나옵니다.
이렇게 바뀌는 this를 동적 this라고 합니다.
따라서 onClickCounter 를 클릭시에 this가 onClickCounter로 바뀌게 됩니다.
변화하는 this를 class로 고정
하기 위해서는 this를 바인딩
해주시거나 화살표 함수
를 써줘야합니다.
이렇게 바인딩 과정을 거쳐서 고정된 this를 렉시컬 this라고 합니다.
컴포넌트의 생명주기는 컴포넌트가 브라우저에 나타나고 업데이트 되고, 사라지게 될 때 호출되는 메서드 입니다.
쉽게 말해, 특정 시점에 코드가 실행되도록 설정할 수 있다는 것입니다.
메서드에 대해 간략히 요약한다면,
render
componentDidMount
componentDidUpdate
componentWillUnmount
class component 생명주기 예제
import { component } from 'react'
export default class ClassCounterPage extends Component {
// class 변수의 선언 방식
state = {
count : 0,
}
// class에서의 함수 사용방식
onClickCouter = () => {
console.log(this.state.conut)
this.setState(((prev)) => ({
count : this.state.count +1 // this.state.count == prev.count
}))
}
// 화면 그리는 부분
render() {
return (
<div>
// this는 class 자기자신을 뜻합니다.
<div>현재 카운트 : {this.state.count}</div>
// 직접 바인딩 하실때는 onClick={this.onClickCouter.bind(this)} 라고 적어주어야 합니다
<button onClick={this.onClickCouter}>카운트 올리기</button>
</div>
)
}
}
페이지가 그려진 후 componentDidMount
를 통해 console.log를 확인할 수 있습니다.
카운트를 올려준 후, componentDidUpdate
를 통해 수정된 사실을 알 수 있습니다.
페이지 이동하기를 통해 componentDidUnmount
가 실행되는 것을 확인할 수 있습니다.
React를 사요하기 전까지 특정 태그에 접근할 때 document.getElementById()
를 사용했습니다.
하지만 React는 실제 DOM이 아닌 virtual DOM(가상돔)을 다루기 때문에 위의 방법으로 접근했을 때 문제가 생길 수 있습니다.
따라서 Ref
를 이용해 태그를 직접 변수에 저장하도록 하겠습니다.
class형 컴포넌트에는 createRef()
메서드를 이용해 특정 태그에 접근합니다.
import {createRef} from 'react'
// Ref코드 생성
inputRef = createRef()
// Ref를 적용하고싶은 input태그(=접근하고싶은 태그)
<input type="text" ref={this.inputRef} />
// 태그에 접근해서 실행시킬 함수
componentDidMout(){
console.log("마운트 됨")
this.inputRef.current?.focus()
}
함수형 컴포넌트에서는 useRef()
훅은 이용해 특정 태그에 접근합니다.
import {useRef} from 'react'
// Ref코드 생성
const inputRef = useRef()
// Ref를 적용하고 싶은 input태그(=접근하고 싶은 태그)
<input type="text" ref={inputRef}/>
// 태그에 접근해서 실행시킬 함수
useEffect(() => {
console.log("마운트 됨")
inputRef.current?.focus()
})
🔔 React는 SPA(Single Page App) 구조입니다.
SPA는 하나의 페이지를 가지는 구조로, virtual DOM으로 여러 컴포넌트를 만들고 필요할 컴포넌트를 조합하고 조합된 컴포넌트를 진짜 돔에 얹어서 보여줍니다.
클래스형 컴포넌트에는 componentDidMount
와 같은 생명주기 메서드들이 있습니다.
그리고 함수형 컴포넌트에서 생명주기와 관련된 훅이 있습니다. 바로 useEffect
입니다.
// 의존성 배열[]에 아무것도 넣지 않으면 Mount시에만 렌더해주고 끝나게 됩니다.(1번만 실행)
useEffect(() => {
console.log("마운트 됨!!")
}, [])
// 의존성 배열이 없기 때문에 뭐 하나라도 바뀌면 무조건 다시 실행됩니다.
useEffect(() => {
console.log("수정하고 다시 그려짐!!")
})
// someState가 수정될때만 리렌더 해주기
useEffect(() => {
console.log("수정하고 다시 그려짐!!")
}, [someState])
useEffect(()=>{
console.log("수정하고 다시 그려짐!!")
// 이부분이 끝나고 진행할 것들
return(() => {
console.log("여기서 나갈래요!!")
})
})
useEffect의 실행 지점
생명주기 메서드, 훅은 기본적으로 render 이후에 실행됩니다.
따라서 useEffect와 lifecycle 메서드는 render 이후에 실행됩니다.
useEffect
안에서 setState
를 사용할때는 정말 필요한 경우가 아니라면 지양하는게 좋습니다.
컴포넌트가 마운트된 이후에 setState
를 적용하게 되면,
1. state가 변경되고
2. 변경된 state로 컴포넌트가 다시 그려지게(re-render) 됩니다.
즉, useEffect
내에서 setState
를 사용하게 되면 불필요한 리렌더나 무한루트를 일으키게 되고 성능면에서 비효율적이게 됩니다.