React-기본문법(3)

Jo-Jun_yeong·2024년 10월 6일

스프레드 연산자

'...'3개의 점으로 표시된다 배열이나 객체와 같은 이터레이브(iterable)객체를 펼쳐서 각 요소를 개별적으로 처리하거나, 복사, 병합 등의 작업을 할 때 자주 사용된다.

배열에서의 스프레드 연산자 사용

배열에서 스프레드 연산자는 배열을 개별 요소로 분해해서 사용할 수 있다.

배열 요소 복사

const arr1 = [1,2,3]
const arr2 = [...arr1]	//arr1을 복사
console.log(arr2)

배열 병합

const arr1 = [1,2]
const arr2 = [3,4]
const merged = [..arr1, ...arr2]//두 배열의 병합
console.log(merged);

함수 인자에 사용

const numbers = [1,2,3]
const add = (a,b,c)=>a+b+c
console.log(add(...numbers))

객체에서의 스프레드 연산자 사용

객체에서도 스프레드 연산자를 사용하여 객체의 복사나 병합을 할 수 있다.

객체 복사

const obj1 = {a:1,b:2}
const obj2={...obj1}
console.log(obj2)

객체 병합

const obj1 = {a:1, b:2}
const obj2 = {b:3, c:4}
const merged = {...boj1, ...obj2}	//두 객체 병합
console.log(merged)	//{a:1, b:3, c:4}

스프레드 연산자의 사례

  • 배열이나 객체의 얕은 복사(Shallow Copy): 원본을 수정하지않고 새로운 배열이나 객체생성 가능
  • 배열/객체의 병합: 여러 배열 또는 객체를 합치는데 사용됨
  • 함수의 인자 전달: 배열 요소를 함수의 개별 인자로 전달할 때 사용됨

map사용법

기본 사용법

'map'메서드는 배열의 각 요소에 대해 주어진 함수를 호출하고, 그 반환값을 새 배열로 만들어 반환한다. React에서는 이 반환된 배열을 JSX로 변환해 UI에 렌더링한다.

예시: 간단한 리스트 렌더링

import React from 'react'

function MyList(){
	const items = ['Apple', 'Banana','Cherry']
    
    return(
    	<ul>
        	{items.map((item, index) => (
            	<li key={index}>{item}</li>	//각 배열의 요소를 <li>로 변환
            ))}
        </ul>
    )
}

export default MyList;

map을 사용한 동적 컴포넌트 렌더링

'map'을 사용하면 배열의 데이터를 기반으로 동적 컴포넌트를 생성하고 렌더링할 수 있다. 예를들어 각요소에 'Card'컴포넌트를 렌더링할 수 있다.

예시:배열을 이용한 컴포넌트 렌더링

function Card ({title, description}){
	return(
    	<div>
        	<h2>{title}</h2>
            <p>{description}</p>
        </div>
    )
}

function CardList(){
	const data= [
    {id:1, title:'Card 1' description:'first Card'},
    {id:2, title:'Card 2' description:'second Card'},
    {id:3, title:'Card 3' description:'third Card'}
    }
    return(
    <div>
    	{data.map((item)=>(
        	<Card key={item.id} title={item.title} description={item.description}/>
        ))}
    </div>
    )
}

위 예시에서 CardList컴포넌트 data배열을 map을 통해 순회하며 각 항목을 Card컴포넌트로 렌더링 한다.

조건부 렌더링과 map

React의 map과 key의 중요성

화살표 함수

코드를 간결하게 작성할 수 있는 방식이다.
특히 this키워드의 바인딩문제에대한 해결에 유용하다.
화살표함수는 주로 컴포넌트의 정의, 이벤트 핸들러 작성, 함수전달에 자주 사용된다.

기본 문법

기존 함수 표현식과 달리 'function'키워드를 사용하지 않고 '=>'를 사용한다

  • 일반 함수 표현식
const testFunction = function (a,b){
	return a+b;
}
  • 화살표 함수 표현식
const testFunction = (a,b)=> a+b;

특징

  • 간결한 문법: 함수의 본문이 한줄이면 return키워드 생략 가능
  • this바인딩: 화살표 함수는 자신만의 this를 가지지않으며 선언될때 컨텍스트에 따라 this가 결정된다.

예시

컴포넌트 정의

React에서 함수형 컴포넌트를 정의할 때 화살표 함수로 쉽게

const TestComponent = () => {
	return <h1>Hello</h1>
}

이벤트 핸들러에 사용

React에서는 이벤트 핸들러를 설정할 떄도 화살표 함수를 자주 사용한다.
특히 화살표함수는 'this'가 자동으로 바인딩 되어있어, 클래스형에서 더 사용하기 편하다.

함수 전달시 간결하게 사용

React에서는 컴포넌트에 함수를 props로 전달할 떄도 화살표함수 문법을 활용할 수 있다.

예시:컴포넌트 간 함수 전달
부모 컴포넌트가 자식 컴포넌트에 이벤트 핸들러를 전달하는 경우:

cont ParentCompo = () => {
	const handleClick = () =>{
    	altert('Button clicked)
    }
    
    return <CHiledCompo onClick={handleClick}/>
}

const ChildCompo = ({onClcik}) => {
	return <button onClick={onClick}> 여기 클릭</button>
}

여기서'ParentCompo'는 'handleClick'함수를 자식 컴포넌트 'ChildCompo'로 전달하고, 자식은 해당 함수를 이벤트 핸들러로 사용할 수 있다.

this바인딩

1. this바인딩이란?

잘 모르겠어서 gpt 긁어옴

함수 내부에서 this키워드가 어떤 객체를 가리키는지 결정하는 메커니즘을 의미한다.
자바스크립트에서 this는 함수가 호출되는 방식에 따라 값이 달라진다.
즉, this는 함수가 실행되는 맥락(Context), 즉 함수가 어디서 호출되는지에따라 가리키는 객체가 달라진다.
일반적인 함수에서 this는 호출한 객체를 참조하며, 이 객체를 this가 "바인딩되었다" 라고 표현한다.

const obj = {
	name: 'Jo',
    greet: function () {
	    console.log(this.name)
    }
}

obj.greet()

위 코드에서 'greet'함수 내부의 'this'는 'obj'객체를 가리킨다.
즉, 'this'함수를 호출한 객체인 'obj'에 바인딩된 상태이다.
만약 함수가 다른 맥락에서 호출된다면, 'this'가 달라질 수 있다.

호출된 곳에 잡혀있다 => 호출된곳에서만 사용되는 값, class에서의 this라고 생각해도 되나?

const greeFunction = obj.greet
greetFunction();	//undefined 출력

위의 경우 'greetFunction'은 'obj'와 관계없이 호출되었기 때문에, 함수 내부에서 this는 전역객체를 가리키며, 'name'속성이 존재하지 않으므로 undefined가 출력된다.

2.화살표 함수에서 "선언될 때 컨텍스트에 따라 'this'가 결정된다"는 의미

화살표함수는 자신만의 'this'를 가지지 않으며, 선언될 당시의 상위 컨텍스트의 'this'를 그대로 상속 받는다. 즉, 함수가 선언된 위치에서의 렉시컬 컨텍스트(Lexical Context)에 따라 'this'가 결정된다.

예시: 화살표 함수에서 'this' 바인딩

const obj = {
	name: 'Jo',
    greet: function() {
    	const innerFunc = () => {
    		console.log(this.name)
        };
		innerFunc();
    }
}

obj.greet()	//Jo출력

위 코드에서 'greet'함수 내부에 있는 'innerFunc'는 화살표 함수 입니다.
화살표 함수는 자신만의 'this'를 가지지 않기 때문에, 'greet'함수가 호출될 때의 'this'를 그대로 상속받스빈다. 즉, 'innerfunc'의' this'는 'obj'객체를 가리킨다.

위의 예제에서 일반함수를 사용했다면

const obj = {
	name: 'Jo',
	greet: function() {
    	const innerFunc = function(){
        	console.log(this.name)
        }
        innerFunc()
    }
}

obj.greet()	//undefined출력

일반함수인 innerFunc는 호출된 방식에 따라 'this'가 결정된다.
여기서 'innerFunc'는 'obj'와는 무관하게 호출되었기 때문에 'this'는 전역객체를 가리키며, 결과적으로는 undefined'가 출력된다.

화살표 함수에서 'this'의 결정 과정

  • 일반함수 에서는 'this'가 함수 호출시점에 결정된다.
  • 화살표 함수에서는 함수 선언시점에 'this'가 상위 스코프의 'this'에 렉시컬(lexical)하게 바인딩 된다.

예시: 사우이 컨텍스트에서 'this'가 바인딩 되는 경우

function OuterFunction() {
	this.name = 'Outer';
    
    const innerFunction = () => {
    	console.log(this.name)
    }
    
    innerFunction()
}

const outerObj = new OuterFunction()

여기서 'innerFunction'은 화살표 함수로 선언되었으며, 'this'는 상위함수인 'OuterFunction'의 'this'를 그대로 상속받는다.
'new OuterFunction()'이 호출되면 'this'는 새로운 객체로 바인딩되고, 화살표 함수 내부에서도 동일하게 그 객체를 참조하게 된다.

정리
1. 'this'바인딩이란 함수 내부에서 'this'가 어떤 객체를 가리키는지 결정하는 메커니즘이다. 일반함수는 호출된 방식에 따라 'this'가 달라지지만, 화살표 함수는 선언될 떄의 상위 컨텍스트의'this'를 그대로 상속받는다
2. "선언될 때 컨텍스트에 따라 this가 결졍된다"는 의미는, 화살표 함수는 호출 시점이 아닌 선언시점에 이미 'this'가 결정된다. 즉, 상위 스코프에서 'this'가 어떤 객체를 가리키고 있는지에 따라 화살표 함수 내부의 'this'가 결정된다.

이벤트 핸들러

React의 이벤트 핸들러는 사용자가 UI와의 상호작용(onClcik, onChange, onMouseMove 등)에 따라 호출되는 함수를 말한다. React에서 이벤트 핸들러는 DOM의 이벤트 처리 방식과 유사하지만, 몇가지 차이점이 있다

React에서의 이벤트 핸들러의 주요 특징

1.CamelCase사용

  • Html에서는 onclick, onchange등 소문자로 이벤트속성을 작성한다.
  • React에서는 카멜표시법을 사용하여 이벤트핸들러를 작성한다.(onClick, onSubmit,...)
<button onClick={handleClick}> Click Me</button>

2.JSX내에 함수 전달

  • 이벤트 핸들러는 ''함수'로 전달되어야 한다. 즉, JSX에서 이벤트 속성에 함수 참조를 전달하거나, 바로 인라인 화살표 함수로 작성할 수 있다.
const handleClick = () => {
	console.log('Button clicked');
}

return <button onClick={handleClick}>Click Me</button>

3.syntheticEvent 사용

  • React는 브라우저의 네이티브 이벤트를 감싸는 SyntheticEvent를 사용합니다
    이는 모든 브라우저에서 일관된 이벤트 동작을 제공하며, React의 가상 DOM을 사용해 성능을 최적화하는 방식이다.
  • SyntheticEvent는 네이티브 DOM이벤트와 거의 동일한 인터페이스를 제공한다.
function handleClick(event) {
	console.log(event.type);
}

return <button onClick={handleClick}> Click</button>

4.SyntheticEvent 기본 동작 방지

  • React에서 'event.preventDefault()'를 호출해 이벤트 기본동작을 방지할 수 있다.
  • HTML 폼 제출시 새로고침 기본동작을 막기위해 주로 사용된다.

클래스형 컴포넌트에서 이벤트 핸들러

클래스형 컴포넌트에서 이벤트 핸들러는 'this'와의 바인딩 문제를 해결해야 합니다. 일반 함수로 입네트 핸들러를 작성하면 'this'가 클래스 인스턴스를 가리키지 않을 수 있게때문에'this'바인딩이 필요하다

  1. 화살표 함수 사용
class MyComponent extends React.Component{
	handleClick = () => {
    	console.log(this)	//this가 MyComponent를 가리킴
    }
    
    render(){
    	return <button onClick={this.handleClick}>Click</button>
    }
}

이벤트 핸들러에 매개변수 전달

이벤트 핸들러에 매개변수를 전달해야 할 때는 화살표 함수를 사용하여 처리할 수 있다.
예를들어, 버튼 클릭마다 특정값 전달하려는 경우

function MyComponent(){
	const handleClic = (value) => {
    	console.log('버튼클릭시의 값', value)
    }
    
    return(
    	<div>
        	<button> onClick={()=> handleClick(1)}값1인 버튼</button>
            <button onClick={()=> handleCluck(2)}>값2인 버튼</button>
        </div>
    )
}

이벤트 핸들러 성능 최적화

이벤트 핸들러를 JSX내에서 직접 정의하는 경우, 렌더링될 때마다 함수가 새롭게 생성된다. 이를 방지하기 위해 함수형 컴포넌트에서는 useCallback 훅을 사용하여 이벤트 핸들러를 메모니제이션할 수 있다.

import React, {useState, useCallback} from 'react'

function MyComponent(){
	const [count, setCount] = useState(0);
    
    const handleClick = useCallback(()=> {
    	setCount(count +1)
    }, [count])
    
    return(
    	<p>Count: {count}</p>
        <button onClick={handleClick}> 상승버튼 </button>
    )
}

이벤트 종류

React에서 지원하는 주요 이벤트는 HTML 이벤트와 유사하며, 다음과 같은 이벤트가 있다.

  • 마우스:onClick, onDounbleClick, onMounseEnter, onMouseLeave
  • 폼 이벤트: onChange, onSubmit, onFocus, onBlur
  • 키보드 이벤트: onKeyDown, onKeyUp, onKeyPress
  • 기타 이벤트: onScroll, onLad,onError

정리

  • React에서 이벤트 핸들러는 사용자 상호작용에 반응하는 함수
  • 이벤트 핸들러는 Calmel표시법으로 작성, 함수 참조를 JSX내에서 전달한다.
  • this바인딩이 필요하며, 화살표 함수를 사용하여 해결 할 수 있다.
  • 함수형 컴포넌트에서 ReactHook과 함께 사용하여 상태와 이벤트를 관리한다.
  • SyntheticEvent는 브라우저의 기본이벤트를 감사써 일관된 입네트 처리를 제공한다.

syntheticEvent

브라우저의 네이티브 DOM이벤트를 감싸는 추상화된 이벤트 객체이다.
이는 React의 가상 DOM(가상DOM)을 통해 일관된 이벤트 처리 시스템을 제공하기 위한 메커니즘이다.

React에서 발생되는 이벤트(클릭,입력,마우스,이벤트 등)는 모두 SyntheticEvent객체를 통해 전달된다.

function handClick(event){
	console.log(event);	//SyntheticEvent 객체 출력
}

<button onClick={handleClick}>클릭</button>

위 코드에서 handClick함수의 event는 브라우저의 네이티브 이벤트가 아닌 SyntheticEvent객체이다.

syntheticEvent특징

(1) 일관된 인터페이스

  • SyntheticEvent는 네이티브 이벤트와 거의 동일한 인터페이스 제공. 예를들어 'event.preventDefault()', 'event.stopPropagation()'같은 메서드를 동일하게 사용할 수 있다.
  • 이는 모든 브라우저에서 동일한 방식으로 작동한다. 따라서 다양한 브라우저에서 발생하는 미묘한 차이를 신경쓸 필요는 없다.

(2) 성능 최적화

  • SyntheticEvent 이벤트 폴링(event Pooling) 이라는 메커니즘을 사용해 성능을 최적화 한다.
  • React는 이벤트가 발생할 떄마다 새로운 이벤트 객체를 생성하는 대신, 이벤트객체를 재사용한다. 즉, 이벤트핸들러가 호출되고 나면 해당 이벤트 객체는 다시 초기화되어 다음 이벤트에서 재사용될 수 있다.
  • 이로인해 메모리 사용을 줄이고 성능개선이 가능하다.

렉시컬 컨텍스트(Lexical Context)

Lexical Context는 자바스크립트에서 변수나 함수가 선언된 위치에 따라 그 범위 가 결정되는 개념이다. 즉, 코드가 작성된 시점에서 어떤 변수를 참조할 수 있는지 정의하는 규칙이다.

  • 렉시컬 스코프 라고도 불리며, 함수가 호출될때가아니라 작성된 위치에 따라 스코프가 결정된다.
  • 함수나 변수는 선언된 위치의 상위 스코프에서만 접근할 수 있다.
profile
5_hero_like

0개의 댓글