자바스크립트에서 다양한 타입의 데이터와 함수를 하나의 변수에 저장할 수 있는 데이터 타입.
const person = {
name: 'John',
age: 20,
sayHello: function() {
console.log('Hello!');
}
}
key와 value의 집합체이다. 위와 같이 프로퍼티(name, age)와 메소드(sayHello)로 구성할 수 있다.
자바스크립트에서 함수와 배열도 실제로는 객체이다.
객체는 복합적인 자료를 효과적으로 관리할 수 있어 프로그래밍에서 매우 중요하며, 객체 지향 프로그래밍 패러다임의 기초가 된다.
프로그래밍 패러다임의 한 종류로, 실세계의 객체와 그 객체들 간의 관계를 프로그래밍하는 방식이다.
이를 바탕으로 객체간 유기적인 협력 관계를 구축한다.
설계의 중요성이 높고 배우기 어렵다는 단점도 있다.
대표적인 OOP 언어로는 자바, 파이썬, C++ 등이 있으며 자바스크립트도 프로토타입 기반의 객체지향을 지원한다.
객체지향 프로그래밍의 상속을 구현하는 방법 중 하나.
자바스크립트는 프로토타입 기반의 객체지향 언어로, 다른 객체의 프로퍼티와 메소드를 상속받을 수 있다.
// 프로토타입 객체
const car = {
wheels: 4,
drive() {
console.log("drive..");
}
}
// car를 프로토타입으로 하는 객체
const bmw = Object.create(car);
bmw.drive(); // drive..
console.log(bmw.wheels); // 4
여기서 bmw는 car 객체를 프로토타입으로 상속받았다.
car 객체의 프로퍼티와 메소드를 사용할 수 있다.
리액트에서도 컴포넌트의 프로토타입 체인을 통해 상속 기능을 제공한다.
자바스크립트에서 객체지향 상속을 구현하는 방법 중 하나.
자바스크립트의 모든 객체는 자신의 부모 역할을 하는 프로토타입 객체를 가리키고 있다. 그리고 부모 객체도 부모를 가리키고 있어, 이들이 프로토타입 체인을 형성하고 있다.
const parent = {
name: 'Parent',
printName() {
console.log(this.name);
}
};
const child = Object.create(parent);
child.printName(); // 'Parent'
여기서 child
객체는 parent
객체를 프로토타입으로 상속받았다.
이때 child
객체에 printName
메서드가 없다면, 자바스크립트 엔진은 프로토타입 체인을 따라 올라가 parent
의 printName
을 찾아서 사용한다.
즉, 연쇄적으로 프로토타입 객체들을 탐색한다는 의미이다.
클래스는 객체 지향 프로그래밍의 한 원리인데, 객체들의 분류와 설계도이다. 자바스크립트 ES6 문법을 통해 도입되었다.
클래스를 사용하면, 객체 인스턴스(즉, 클래스로 정의한 객체)를 생성하고, 공통된 특성과 기능을 구현할 수 있다.
class Cat {
constructor(name) {
this.name = name;
}
meow() {
console.log(`${this.name}야 옹옹!`);
}
}
const myCat = new Cat("나비");
myCat.meow();// 나비야 옹옹!
이렇게 Cat
클래스로부터 나비라는 Cat
인스턴스를 생성하고 기능을 사용할 수 있다.
리액트에서는 컴포넌트를 클래스 형태로 정의할 수 있다.
class MyComponent extends React.Component {
render() {
return <div>Hello</div>;
}
}
컴포넌트를 클래스로 정의하면 해당 컴포넌트 자체가 인스턴스가 되고 메소드 및 상태를 가질 수 있게 된다.
리액트에서 해당 컴포넌트를 가리킨다.
리액트 컴포넌트를 클래스 형태로 정의하면 이 컴포넌트 자체가 하나의 인스턴스이다.
class MyComponent extends React.Component {
render() {
return <div>Hello</div>;
}
}
const myComponent = new MyComponent();
여기서 myComponent
가 바로 MyComponent
의 인스턴스이다.
클래스 컴포넌트 내부에서는 this 키워드를 통해 자신의 인스턴스에 접근할 수 있다.
this.state// 인스턴스의 state
this.props// 인스턴스의 props
함수 컴포넌트의 경우 별도의 인스턴스 개념이 없지만,
ref를 통해 해당 컴포넌트 자체를 참조할 수 있다.
const myComponent = useRef(null);
<MyComponent ref={myComponent}/>
여기서 myComponent.current
가 바로 이 함수형 컴포넌트의 인스턴스가 된다.
특정 DOM 노드나 리액트 컴포넌트 인스턴스에 대한 참조(reference)를 만들어주는 것.
const myElement = useRef(null);
<div ref={myElement}>
Hello!
</div>
여기서 myElement
는 해당 div 엘리먼트의 참조가 저장되어 있다.
myElement.current
를 통해 이 div 엘리먼트에 직접적으로 접근할 수 있다.
ref의 주요 사용처
이처럼 DOM이나 컴포넌트 접근 시 reference로 사용된다.
리액트 훅(Hook) 중 하나로, 함수형 컴포넌트에서 ref를 쉽게 사용할 수 있도록 해준다.
const ref = useRef(initialValue);
useRef
가 하는 일
DOM의 참조 - 특정 DOM에 대한 참조(reference)를 만들어준다.
예를 들어 특정 엘리먼트에 focus를 주고 싶은 경우, 이 엘리먼트를 참조할 수 있도록 useRef를 사용한다.
const inputEl = useRef(null);
<input ref={inputEl} />
inputEl.current.focus();
렌더링 비참조 값의 유지 - 렌더링과 관계 없이 바뀔 수 있는 값을 관리한다.
useRef
로 관리하는 값은 렌더링에 영향을 주지 않으면서 컴포넌트의 생명주기를 벗어나지 않고 유지할 수 있다.
이를 활용하여 이전 값을 저장하는 용도 등으로 사용할 수 있다.
const id = useRef(1);
id.current++; // 렌더링과 무관하게 current 값 1 증가 (값 유지 및 변경 가능)
useRef
가 반환하는 객체가 기본적으로 가지고 있는 특별한 프로퍼티
const id = useRef(1);
return <div>ID: {id.current}</div>
이때 id.current
를 통해 현재 가리키고 있는 값에 접근할 수 있다.
이 값은 컴포넌트의 리렌더링에 영향을 받지 않기 때문에, 부수 효과 없이 변수를 관리할 수 있다.