자바스크립트 리액트 - 객체, 클래스, 인스턴스, ref, useRef, current

지인·2024년 5월 27일
1

객체 (Object)

자바스크립트에서 다양한 타입의 데이터와 함수를 하나의 변수에 저장할 수 있는 데이터 타입.

const person = {
  name: 'John',
  age: 20,
  sayHello: function() {
    console.log('Hello!');
  } 
}

key와 value의 집합체이다. 위와 같이 프로퍼티(name, age)와 메소드(sayHello)로 구성할 수 있다.

  • 키-값 쌍의 자료 구조
  • 값으로 다양한 데이터 타입이 가능
  • 메소드도 값으로 가질 수 있음
  • 동적 추가와 삭제 가능

자바스크립트에서 함수와 배열도 실제로는 객체이다.
객체는 복합적인 자료를 효과적으로 관리할 수 있어 프로그래밍에서 매우 중요하며, 객체 지향 프로그래밍 패러다임의 기초가 된다.

객체 지향 프로그래밍(OOP)

프로그래밍 패러다임의 한 종류로, 실세계의 객체와 그 객체들 간의 관계를 프로그래밍하는 방식이다.

객체 지향의 핵심 원리

  • 추상화 - 현실 세계를 프로그램 설계에 반영
  • 캡슐화 - 객체의 속성과 기능을 하나로 묶음
  • 상속 - 다른 객체의 속성과 기능을 물려받을 수 있음
  • 다형성 - 객체들이 같은 메시지에 대해 다르게 응답할 수 있음

이를 바탕으로 객체간 유기적인 협력 관계를 구축한다.

장점

  • 복잡한 문제를 객체 단위로 쪼개어 해결
  • 코드 재사용성 증가
  • 유지보수 용이

단점

설계의 중요성이 높고 배우기 어렵다는 단점도 있다.

대표적인 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 메서드가 없다면, 자바스크립트 엔진은 프로토타입 체인을 따라 올라가 parentprintName을 찾아서 사용한다.
즉, 연쇄적으로 프로토타입 객체들을 탐색한다는 의미이다.

클래스

클래스는 객체 지향 프로그래밍의 한 원리인데, 객체들의 분류와 설계도이다. 자바스크립트 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가 바로 이 함수형 컴포넌트의 인스턴스가 된다.

ref

특정 DOM 노드나 리액트 컴포넌트 인스턴스에 대한 참조(reference)를 만들어주는 것.

const myElement = useRef(null);

<div ref={myElement}>
  Hello!
</div>

여기서 myElement는 해당 div 엘리먼트의 참조가 저장되어 있다.
myElement.current를 통해 이 div 엘리먼트에 직접적으로 접근할 수 있다.

ref의 주요 사용처

  • 특정 DOM에 직접 접근해야 할 때 (스크롤, 포커스 등)
  • 컴포넌트 내부에서 특정 자식 컴포넌트에 접근할 때
  • 컴포넌트와 관련된 값을 저장할 때

이처럼 DOM이나 컴포넌트 접근 시 reference로 사용된다.

useRef

리액트 훅(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 증가 (값 유지 및 변경 가능)

current 프로퍼티

useRef가 반환하는 객체가 기본적으로 가지고 있는 특별한 프로퍼티

const id = useRef(1); 

return <div>ID: {id.current}</div> 

이때 id.current를 통해 현재 가리키고 있는 값에 접근할 수 있다.
이 값은 컴포넌트의 리렌더링에 영향을 받지 않기 때문에, 부수 효과 없이 변수를 관리할 수 있다.

0개의 댓글