[목차]
- React 설치 방법
- React 생명 주기
React 설치
1. Node.js 설치
2. React 설치
vscode에서 폴더 열기
위와 같은 오류가 발생할 때,
Windows PowerShell을 실행 후 Get_ExecutionPolicy 명령어를 입력하게 되었을 때, Restricted라고 나온다면 바꿔줘야한다.
Set-ExevutionPolicy RemoteSigned
Set-ExevutionPolicy RemoteSigned를 입력해 변경해주면 오류를 해결할 수 있으며 프로젝트가 잘 생성된다!
React 생명주기
*클래스 컴포넌트 – 라이프 사이클 메서드 사용
*함수형 컴포넌트 – Hook 사용
① 마운트(생성)
컴포넌트의 인스턴스가 생성되어, DOM에 삽입될 때 아래의 순서대로 호출된다.
1.constructor | 컴포넌트 생성자 메서드, 컴포넌트가 생성되면 가장 먼저 실행되는 메서드로 this.props, this.state에 접근이 가능하고 리액트 요소를 반환한다. |
2.getDerivedStateFromProps | props로부터 파생된 state를 가져온다. 즉, props로 받아온 것을 state에 넣어주고 싶을 때 사용 |
3.render | 컴포넌트를 렌더링하는 메서드 |
4.componentDidMount | 컴포넌트가 마운트 됨. 컴포넌트의 첫 번째 렌더링이 마치면 호출되는 메서드. 이 메서드가 호출되는 시점에는 화면에 컴포넌트가 나타난 상태다. 여기서는 주로 DOM을 사용해야 하는 외부 라이브러리 연동, 해당 컴포넌트에서 필요로 하는 데이터를 ajax로 요청 등을 한다. |
② 업데이트
Props나 state가 변경되면 렌더가 진행되며 순서대로 호출된다.
③ 언마운트
●useEffect
- 리액트 컴포넌트가 렌더링 될 때마다 특정 작업(effect)을 실행할 수 있도록 하는 hook으로, component가 mount, update, unmount 됐을 때 작업을 처리할 수 있다.
- hook에서 클래스 컴포넌트의 기능을 사용하기 위해 만들어진 것이므로. useEffect()가 아래 생명주기 함수들을 수행한다. (componentDedMount, componentDidUpdate, compoonentWillUnmount, getDerivedStateFromProps)
1 | useEffect(callBackFunc); | 렌더링이 될 때마다 (컴포넌트가 마운트 된 후, 컴포넌트가 업데이트되고 난 후, 컴포넌트가 언마운트 되기 전에) 실행된다. |
2 | useEffect(callBackFunc, []); | 컴포넌트가 최초 렌더링 되었을 때만 실행이 된다. 즉, 생명주기 메소드의 componentDidMount의 역할을 수행한다. |
3 | useEffect(callBackFunc, [state1, state2]); | 최초 렌더링 + state1 또는 state2가 변경되었을 때 실행된다. 생명주기 메소드의 componentDidUpdate, getDerivedStateFromProps의 역할을 수행한다. |
4 | useEffect(() => {return(() => func()) }); | useEffect는 clean-up이라고 표현하는 함수를 return 할 수 있는데, cleap-up 함수(리턴하는 함수)를 활용해 컴포넌트가 unmount될 때 정리하거나 unscribe해야할 것을 처리하낟. 즉, clean-up함수는 생명주기 메소드의 componentWillUnmount의 역할을 수행한다. |
●외부스크립트 import할 수 있는 방법
scriptImport : function (PageURL) { var scriptURL = "스크립트 URL"; var scriptElement = document.createElement("script"); scriptElement.src = scriptURL; document.body.appendChild(scriptElement); }, |
- React 모듈 만드는 방법
nodejs 모듈 만들기 => 여러가지 exports 방식이 있음.(ex. module.exports)
- export 객체
export 객체 : 모듈의 생성
module.exports.모듈외부에서사용할이름 = 모듈 내부에서의 이름; |
//calc1.js function add(a, b) { return a + b; } function sub(a, b) { return a – b; } module.exports.add = add; module.exports.sub = sub; |
//calc2.js var calc = {} calc.add = function(a, b) { return a + b; } calc.sub = function(a, b) { return a – b; } module.exports = calc; |
//calc2.js exports.add = function(a, b) { return a + b; } exports.sub = function(a, b) { return a - b; } |
1. 2개 이상의 함수를 export 하는 방법
function edit() {} function write() {} |
|
방법 1) module.export = { edit, write } |
방법2) module.exports = { edit : edit write: write } |
2. 변수나 함수, 클래스를 선언할 때 맨 앞에 export를 붙이면 내보내기가 가능하다.
// 배열 내보기 export let months = [‘Jan’, ‘Feb’, ‘Mar’, …, ‘Dec’ ]; // 상수 내보내기 export const MODULES_BECAME_STANDARD_YEAR = 2023; // 클래스 내보내기 export class User{ constructor(name){ this.name = name; } } |
*class나 함수를 내보낼 땐 세미콜론을 붙이지 않는다.
export function sayHi(user) { alert(`Hello ${user}!`); } // 끝에 ;(세미콜론)을 붙이지 않는다. |
*생성자 함수에 Script id가 있으면(즉, 스크립트가 설치가 되어 있으면) 실행되지 않도록 구현
- Private, pubic, 멤버변수
*함수를 호출하는 객체가 있으면 메소드, 없으면 함수!
*property(프로펄티) : 객체 안에 선언된 이름과 값으로 이루어진 한 쌍을 의미한다.
- Getter, Setter
Getter와 Setter는 객체 지향 프로그래밍에서 사용되는 개념이며, 일조의 메서드라고 보면 된다. Getter는 객체의 속성(property) 값을 반환하는 메서드이며, Setter는 객체의 속성 값을 설정, 변경하는 메서드이다.
let obj = { get propName() { // getter, obj.propName을 실행할 때 실행되는 코드 }, set propName(value) { // setter, obj.propName = value를 실행할 때 실행되는 코드} }; |
- Getter, Setter를 사용하는 이유
> Getter와 Setter를 사용하면 객체 내부 속성에 직접 접근하지 않아 객체의 정보 은닉을 가능하게 해주어 보안을 강화할 수 있고, 코드의 안전성과 유지보수성을 높일 수 있다는 장점이 있다. 또한, 옳지 않은 값을 넣으려고 할 때 이를 미연에 방지할 수 있다.
> setter 메소드를 추가한 순간 => 값을 할당하려고 시도하면 프로퍼티의 값에 직접 할당하지 않고 setter를 호출하게 된다. Setter 함수 내에 그 값을 할당해도 되는지 검사한 이후에 값을 할당한다.
> getter 메소드를 추가한 순간 => 값을 사용하려고 시도하면 메모리에 저장된 값을 불러오지 않고 getter를 호출하게 된다. this.변수를 사용하려고 시도할 때 get 함수를 호출하게 되고 setter로 할당된 값인 this.변수를 리턴하게 된다.
*”Maximum call stack size exceeded” 오류
=> getter 메소드(혹은 setter)와 프로퍼티 이름을 같게 하면 무한 반복 오류가 발생할 수 있음.
이유) 아래 코드에서 get age() 메서드의 내부에서 this.age로 프로퍼티에 접근하고 있습니다. 하지만 this.age는 get age() 메서드 자체를 호출하게 됩니다. 따라서 get age() 메서드가 호출되면 다시 this.age를 호출하고, 이렇게 반복적으로 자기 자신을 호출하게 되면서 무한한 재귀 호출이 발생하게 됩니다. 이러한 재귀 호출이 스택에 계속 쌓이다가 호출 스택 크기를 초과하여 "Maximum call stack size exceeded" 오류가 발생합니다.
class Person { constructor(name, age) { this.name = name; this.age = age; } // age 프로퍼티의 getter 메서드 정의 get age() { return this.age; // 여기서 this.age는 getter 메서드 자체를 호출하게 됨 } } const person = new Person('John', 30); console.log(person.age); // 무한 반복 오류가 발생함 |
해결 방안)
① "getter" 메서드 내에서 해당 프로퍼티에 접근할 때, this._age와 같이 실제 프로퍼티명 앞에 _를 붙여서 직접 프로퍼티를 참조하는 것이 일반적인 방법
get age() { return this._age; } |
② 메서드 이름과 프로퍼티 이름을 구분하여 사용하면 재귀 호출로 인한 무한 반복 오류를 피할 수 있다.
class Person { constructor(name, age) { this.name = name; this.age = age; } // getAge() 메서드 정의 getAge() { return this.age; } } const person = new Person('John', 30); console.log(person.getAge()); // 출력: 30 |
ð 이렇게 되면 내부적인 프로퍼티인 _age에 값이 할당되고 리턴된다!
- class vs prototype
> Class
ES6부터 도입된 클래스는 객체 지향 프로그래밍의 기본 개념을 JavaScript에 추가한 것이다. 클래스는 생성자 함수와 메서드를 묶어서 객체를 생성하고 구조화하는 방식을 제공한다. 클래스를 사용하면 객체를 만들고 상속을 구현하기가 훨씬 간단하고 명료해진다.
class Person { constructor(name, age) { this.name = name; this.age = age; } sayHello() { console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`); } } const john = new Person('John', 30); john.sayHello(); // 출력: Hello, my name is John and I am 30 years old. |
> prototype
프로토타입은 JavaScript의 객체 지향 프로그래밍에서 객체 간 상속과 메서드 공유를 위한 메커니즘이다. 모든 JavaScript 객체는 ‘__proto__’라는 프로퍼티를 가지며, 이를 통해 다른 객체를 상속하고 해당 객체의 메서드와 프로퍼티를 공유할 수 있다.
프로토타입은 다음과 같이 객체 생성자 함수 아래에 “.prototype.[원하는키] =” 코드를 입력하여 설정 할 수 있습니다.
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`); }; const john = new Person('John', 30); john.sayHello(); // 출력: Hello, my name is John and I am 30 years old. |