이벤트 연결하는 법

- jsx에서 camelCase 형태의 속성에 함수를 전달함.

import { useCallback } from "react";

// 컴포넌트 외부에 함수 선언
function handleClick2(e) {
  console.log("click2", e);
}

function App() {
   /**
   * 합성 이벤트 (SyntheticEvent)
   * - React에서 이벤트가 발생할 때, 이벤트 핸들러의 인자로 합성 이벤트 객체가 전달됨
   * - 이 합성 이벤트는 javascript에서 전달 받는 이벤트 객체를 확장(래핑)한 객체임
   *   (거의 동일한 인터페이스를 가지고 있음)
   * - 원본 이벤트 객체(native event)는 syntheticEvent.nativeEvent 에 있음
   * - 지금은 그냥 같은 이벤트 객체라고 생각해도 무방
   */
  function handleClick1(e) {
    console.log("click1", e);
  }
  
  /**
   * 이벤트 핸들러(함수)를 만들 때는 react lifecycle을 고려하자!
   *  - 컴포넌트가 리랜더링 되면 컴포넌트 내에서 단순 정의한 함수가 새로운 함수로 만들어짐
   *  - 이것은 불필요한 작업으로 성능 문제를 야기함
   *  - 그래서 함수의 정의를 최대한 컴포넌트 밖으로 빼거나,
   *    useCallback으로 감싸줘서 매 랜더링 마다 새로 만들어지지 않도록 해줄 필요가 있음
   */
  const handleChange = useCallback((e) => {
    console.log("change", e.target.value);
  }, []);

  return (
    <div>
      <button onClick={handleClick1}>Button1</button>
      <button onClick={handleClick2}>Button2</button>
      <div>
        <input type="text" onChange={handleChange} />
      </div>
    </div>
  );

}

 

이벤트 종류

Mouse 이벤트

- onClick, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave, onMouseMove

Keyboard 이벤트

- onKeyDown(물리적인 키에 반응), onKeyUp, onKeyPress(실제적으로 문자가 들어왔을 때만 반응)

Focus 이벤트

 - onFocus(요소가 포커스 될 때), onBlur(요소의 포커스가 사라졌을 때)

- Form 이벤트: onChange

 

Form 요소

Controlled Component (제어 컴포넌트)

- React에 입력 요소의 값이 제어되는 컴포넌트

- 장점 : 컴포넌트의 state와 input value가 완전히 동일한 값을 갖음 (신뢰가능한 출처)

다른 component에 input value를 전달하거나 다른 이벤트 핸들러에서 값을 재설정할 수 있음.

- 단점 : 값이 변경되는 매 순간 렌더링 됨.

'Javascript > React' 카테고리의 다른 글

React의 Life Cycle 이해 - Hooks  (5) 2025.01.08
컴포넌트, Props, State  (3) 2025.01.07
React JSX (javascript xml)  (1) 2025.01.06
React란?  (0) 2025.01.06

Hooks 

- React life cycle을 이해하기 위해 알아야 함.

- 종류

    - useState 

    - useEffect

    - useCallback

    - useMemo, useContext, useRef, useLayoutEffect

useState

/**
   * useState: 상태 값과 그 값을 갱신하는 함수를 반환
   * - 인자: 초기 상태 값
   * - 반환: [상태 변수, 상태에 대한 Setter]
   */
  const [value, setValue] = useState(0);

useEffect

/**
 * useEffect: 컴포넌트가 렌더링 될 때, 특정 작업을 실행
   * - 인자
   *   - 실행하고자 하는 함수 (effect callback)
   *     - effect는 정리(clean-up) 함수를 반환할 수 있음
   *     - 반환된 함수는 컴포넌트가 언마운트 또는 effect 재실행 이전에 실행됨
   *   - 의존성 배열 (dependency list)
   */
  useEffect(() => {
    console.log("[Function] useEffect []: 컴포넌트가 마운트 될 때, 한 번만!");

	//마운트가 됐을 때! eventListener를 넣기 (밖에 두면 이벤트가 중복돼서 만들어짐)
    //document.body.addEventListener('click', ()=>{console.log('click body');});
    
    //언마운트가 됐을 때 남아있는 리소스를 제거해야 이벤트가 발생하는 문제를 해결할 수 있음!!
    const eventHandler = () => {console.log('click body')};
    document.body.addEventListener('click', eventHandler);
    
    return () => {  //cleanup함수라고 함.
      console.log("[Function] useEffect return []: 컴포넌트가 언마운트 될 때,");
      document.body.removeEventListener('click', eventHandler); 
    };
  }, []);
  
  
  useEffect(() => {
    console.log(
      "[Function] useEffect [value]: 컴포넌트가 마운트 될 때, + value가 변경되면,"
    );

    return () => { //cleanup함수라고 함.
      console.log(
        "[Function] useEffect return [value]: 새로 useEffect를 수행하기 전에,"
      );
    };
  }, [value]); //두번째 인자에 이렇게 넣고, value가 변경될 때 실행하도록할 수 있음
  
  //value가 변경되고 -> 다시 랜더링되면서 컴포넌트의 첫줄부터 시작 -> useEffect return(cleanup함수) -> 
  //useEffect의 첫줄 실행되는 순으로 진행됨.

 

useCallback

- 성능을 위해서 

/**
   * useCallback: 메모이제이션된 콜백을 반환
   * - 인자
   *   - 메모이제이션 할 함수
   *   - 의존성 배열
   * - 반환: 메모이제이션 된 함수
   * *의존성 배열을 제대로 셋팅하지 않으면 함수 안에서 사용되는 값이 업데이트 되지 않은 값일 수 있음
   */
   
   
  //[비교] useCallback 없이 사용할 때, 리랜더링될 때마다 아래 함수를 계속 만들어줌 ... 가비지컬랙터가 작동된다고 해도 중복해서 만드는 것은 성능에 좋지 않다.
  const increaseValue = () => {setValue(value+1);};
  //[비교] useCallback, 처음에 랜더링됐을 때 한번 만들어놨으면 두번째 랜더링에 와서 기존에 있던 걸 기억해서 재활용하는 식으로 동작
  const increaseValue = useCallback(
    () => {setValue(value + 1);}, [value] //value 값이 변할 때, 함수 만들도록 함. value가 없다면 1.. (처음 value값이 0일 때.. 계속 재활용하면 1로 세팅) 
  );
  //사실 위 상황은 useCallback이 필요한 상황이 아님. (예시를 위한 것일 뿐)
  const resetValue = useCallback(() => { setValue(0); }); //value와 같은 디펜던시가 없음. 처음 만든 함수를 계속 재활용해도 된다는 소리임.
  

  return (
    <div>
      <h1>value: {value}</h1>
      <button onClick={increaseValue}>Increase value</button>
    </div>
  );

 

Hooks를 사용할 때 주의사항
- 조건문 안에 사용해서는 안 된다.
- React 컴포넌트에서만 사이클 관리를 위해 쓰이는 것이기 때문에 함수 안에 사용해서도 안 된다.

 

React 랜더링 과정

클래스형 컴포넌트의 Life Cycle

함수형 컴포넌트의 Life Cycle

'Javascript > React' 카테고리의 다른 글

React 이벤트 핸들링  (2) 2025.01.09
컴포넌트, Props, State  (3) 2025.01.07
React JSX (javascript xml)  (1) 2025.01.06
React란?  (0) 2025.01.06

컴포넌트

컴포넌트란?

- 스스로 상태를 관리하는 캡슐화된 코드 조각

- (기술적으로) 하나의 JSX를 반환하는 함수

//App.js
export default function App() { //export default 다른 컴포넌트에서 사용하기 위함.
	return (
    	<div>
        	<h1>Hello,</h1>
            <h2>World</h2>
        </div>
    );
}
-------------------------
//index.js
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
	<App />, //App 컴포넌트
    document.getElementById('root');
);
---------------------------

 

컴포넌트 만들기

- JSX 형태로만 컴포넌트를 만드는 것 -> 함수형태로 컴포넌트를 만드는 것

  : 함수라는 scope 개념이 생기면서 고유한 로직이 들어갈 수 있고, 컴포넌트 스스로 상태를 가질 수 있음.

- import, export 문법 사용 (es6에서 모듈을 불러오고 내보내는 방법)

- 컴포넌트 이름은 PascalCase로 지어야 함 (단어의 시작 문자를 대문자)

- 컴포넌트는 의미단위로 쪼개서 파일을 분리

 

Props

Props란?
- 부모 컴포넌트에서 자식 컴포넌트로 내려주는 데이터

// 부모에서 자식으로 데이터를 내려줌.
function App() { //부모
	return (
    	<div>
        	<MyComponent value={'test'}/>
        </div>
    );
}

function MyComponent(props) { //자식
	return <div>{props.value}</div>;
}

--------------------------------------
// 컴포넌트 태그로 감싼 값이 props.children으로 전달됨.
function App() {
	return (
    	<div>
        	<MyComponent>
            	<h1>value</h1> 
            </MyComponent>
        </div>
    );
}

function MyComponent(props) {
	return <div>{props.children}</div>; //<h1>value</h1> 
}

Props 활용 팁

- 구조분해할당 구문을 잘 활용하자

- 특정 Props에 기본 값을 줄 수 있음

- Props는 읽기 전용

 

//Heading.js

export default function Heading(props) {
  if (props.type === "h2") {
    return <h2>{props.children}</h2>;
  }

  return <h1>{props.children}</h1>;
}

//index.js

import Heading from "./components/Heading";
export default function App() {
  return (
    <div>
      <Heading type="h1">test</Heading>
      <Heading type="h2">World</Heading>
    </div>
  );
}

 

State

State란
- 컴포넌트(상태를 관리) 내부에서 사용되는 변수


- State 값이 변하면 컴포넌트가 리렌더링 됨
- 렌더링 사이클에서 값이 보존됨

import { useState } from "react";

export default function App() {
  let [value, setValue] = useState(0);
  return (
    <div>
      <h1>value: {value}</h1>
      <button
        onClick={() => {
          console.log("Increase value1", value); 
          setValue(value + 1);
          console.log("Increase value2", value);
          //위 아래 콘솔 로그 모두 같은 값으로 찍힘(증가 전 값으로 나타남): 이유는 모든 랜더링이 끝난 후 한꺼번에 모아서 setState으로 변경을 해주기 때문.!!
        }}
      >
        Increase value
      </button>
  );
}

 

클래스형 컴포넌트 vs. 함수형 컴포넌트 (위)

클래스형 컴포넌트 

- 클래스 문법으로 구현한 컴포넌트

- useStatae와 같은 Hooks는 React 버전 16.8부터 사용 가능 (그 전에는 클래스형 컴포넌트만 state를 가질 수 있었음)

- 클래스의 멤버 변수로 state 정의

- render라는 멤버 함수에서 반환한 값이 화면에 그려짐

 

import React, { Component } from 'react';

export default class App extends Component {
  state = {
    value: 0
  };

  constructor(props) {
    super(props);
    this.state = {
      value: 1
    };
  }

  resetValue() {
    this.setState({ value: 0 });
  }

  render() {
    return (
      <div>
        <h1>value: {this.state.value}</h1>
        <button
          onClick={() => {
            this.setState((state) => ({ //Component의 함수 setState : 컴포넌트에 값이 바뀌었다고 알림. -> render 함수 다시 실행
              value: state.value + 1
            }));
          }}
        >
          Increase value
        </button>
        <button
          onClick={this.resetValue.bind(this)} //bind 안쓰면 this를 button 요소를 가리켜 오류.
        >
          Reset value
        </button>
      </div>
    );
  }
}

'Javascript > React' 카테고리의 다른 글

React 이벤트 핸들링  (2) 2025.01.09
React의 Life Cycle 이해 - Hooks  (5) 2025.01.08
React JSX (javascript xml)  (1) 2025.01.06
React란?  (0) 2025.01.06

JSX = html + javascript

-react는 JSX를 활용해서 컴포넌트(화면)을 그린다.

React 라이브러리

- react : 리액트의 핵심 코드들이 담겨 있음.

- react-dom : 핵심 코드들로 구현한 화면을 dom에 연결시킬 때 사용

- react-scripts : 리액트로 구현한 코드를 실행하거나, 빌드할 때 사용하는 스크립트들을 모아둠.

JSX의 특징

import ReactDOM from 'react-dom';

let text = 'Hello, world!';
const num = 15;
const obj = { key: 0, a: 1, b: 2 };
const arr = ['a', 'b', 'c'];
const imageUrl =
  'https://dst6jalxvbuf5.cloudfront.net/static/img/logo/logo.svg';

const element = (
  <div>
    <h1>변수 넣기</h1>
    <ul>
      <li>{text}</li>
      <li>{text + 'test'}</li>
    </ul>
    <h1>숫자 및 계산식 넣기</h1>
    <ul>
      <li>{num}</li>
      <li>{num + 15}</li>
    </ul>
    <h1>Boolean, Nullish 값 넣기</h1>
    <ul> /* 아래 항목들은 아무것도 출력되지 않음 */
      <li>{true}</li>
      <li>{false}</li>
      <li>{undefined}</li>
      <li>{null}</li>
    </ul>
    <h1>Object, Array 넣기</h1>
    <ul>
      {/* <li>{obj}</li> obj는 이런 식으로 넣을 수 없음. */}
      <li>{arr}</li>
    </ul>
    <h1>주석 넣기</h1>
    <ul>
      <li>{/* 주석입니다. */}</li>
    </ul>
    <h1>태그 속성에 넣기</h1>
    <ul>
      <li>
        <img src={imageUrl} alt="logo" />
      </li>
    </ul>
  </div>
);

ReactDOM.render(
  element,
  document.getElementById('root')
);

- jsx에서 사용되는 태그의 속성 이름이 html과 다름.

- 태그를 명시적으로 닫아줘야 함.

- 하나의 태그로 감싸져있어야 함. (div)

- 중괄호로 태그 안에 넣어서 js 변수 사용할 수 있음.

 

 

import ReactDOM from 'react-dom';

const arr = [1, 2, 3];
const text = '';

const element = (
  <div>
    <h1>삼항연산자</h1>
    <ul>
      <li>
        {1 + 1 === 2
          ? '참입니다.'
          : '거짓입니다.'}
      </li>
    </ul>

    <h1>AND 연산자</h1>
    <ul>
      <li>{1 + 1 === 2 && 'AND 연산자1'}</li>
      <li>{arr.length && 'AND 연산자2'}</li>
    </ul>

    <h1>OR 연산자</h1>
    <ul>
      <li>{1 + 1 !== 2 || 'OR 연산자1'}</li>
      <li>{text || 'OR 연산자2'}</li>
    </ul>

    <h1>IF문 (즉시실행함수)</h1>
    <ul>
      <li>
        {(() => {
          if (1 + 1 === 2) return 'IF';
          else return 'ELSE';
        })()}
      </li>
      <li>
        {(() => {
          const data = '즉시실행함수';

          /* 어떤 연산이든 추가 가능 */
          /* 일반적으로는 이렇게 즉시실행함수가
         미리 위에서 가공하여 전달 */

          return data;
        })()}
      </li>
    </ul>
  </div>
);

ReactDOM.render(
  element,
  document.getElementById('root')
);

- jsx에서 중괄호로 javascript에서 쓰이는 값들 모두 넣을 수 있다 !

- 논리 연산자는 아래 같은 형태로 많이 쓰임 

   - {true/false && '문자열'} -> 앞이 true면 (뒤에 내용 봐야 하니까) 문자열 그대로 출력, false면 아무것도 출력하지 않음.

   - {true/false || '문자열'} -> 앞이 true면 아무것도 출력하지 않음, false면 (뒤에 내용 봐야 하니까) 문자열 그대로 출력.

- 즉시실행함수를 넣어서 쓸 수 있지만(if문은 이런식으로 밖에 쓸 수 없음), 이렇게 로직을 넣는것은 사실 별로 좋지 않음. 

 

 

반복문
- Warning: Each child in a list should have a unique "key" prop.

* jsx에서 반복문을 돌릴 때, key 속성을 필수로 넣어줘야 한다. (react 내부적으로 각각의 item을 구분하기 위해 사용하는 고유의 id) *

 

[Before : 요소에 키 속성이 없어서 오류 발생]

import ReactDOM from 'react-dom';

const arr = ['1번', '2번', '3번'];

const arr2 = [];
for (let i = 0; i < arr.length; i++) {
  arr2.push(<h4>{arr[i]}</h4>);
  // = [<h4>1번</h4>, <h4>2번</h4>, <h4>3번</h4>]
}

const element = (
  <div>
    <h1>배열로 넣기</h1>
    <ul>
      <li>{arr}</li>
      <li>{arr2}</li>
    </ul>

    <hr />

    <h1>Array.map</h1>
    <ul>
      <li>
        {arr.map((item) => {
          return <h4>{item}</h4>;
        })}
      </li>
    </ul>
  </div>
);

ReactDOM.render(
  element,
  document.getElementById('root')
);

 

[After : key 속성 추가]

import ReactDOM from "react-dom";

const arr = ["1번", "2번", "3번"];

const arr2 = [];
for (let i = 0; i < arr.length; i++) {
  arr2.push(<h4 key={i}>{arr[i]}</h4>);
  // = [<h4>1번</h4>, <h4>2번</h4>, <h4>3번</h4>]
}

const element = (
  <div>
    <h1>배열로 넣기</h1>
    <ul>
      <li>{arr}</li>
      <li>{arr2}</li>
    </ul>

    <hr />

    <h1>Array.map</h1>
    <ul>
      <li>
        {arr.map((item, index) => {
          return <h4 key={`${item}-${index}`}>{item}</h4>;
        })}
      </li>
    </ul>
  </div>
);

ReactDOM.render(element, document.getElementById("root"));

 

CSS 적용하여 스타일링하기
- CSS IN JS (나중에 라이브러리로 확인 가능) vs. CSS IN CSS (전통) 

* jsx에서는 style에 문자열이 아닌 오브젝트(key-value) 속성으로 넣어서 사용한다 *

import './index.css';

import ReactDOM from 'react-dom';

// 2. style 재활용
const roundBoxStyle = {
  position: 'absolute',
  top: 50,
  left: 50,
  width: '50%',
  height: '200px',
  padding: 20,
  background: 'rgba(162,216,235,0.6)',
  // 3. 속성은 camelCase
  borderRadius: 50
};

const element = (
  <div
    style={{
      // 1. Object로 css 작성
      position: 'relative',
      width: 400,
      height: 1000,
      background: '#f1f1f1'
    }}
  >
    <div style={roundBoxStyle}>Hello1</div>

    <div style={{ ...roundBoxStyle, top: 350 }}>
      {/* 4. className을 통한 스타일링 (CSS-in-JS) */}
      <div className={"highlight"}>Hello2</div>
    </div>

    <div style={{ ...roundBoxStyle, top: 650 }}>
      {/* 5. 조건적 스타일 */}
      <div
        className={
          1 + 1 === 2 ? 'highlight' : false
          //= 1+1 === 2 && 'highlight'
        }
      >
        Hello3
      </div>
    </div>
  </div>
);

ReactDOM.render(
  element,
  document.getElementById('root')
);



/*
css 파일 내용

.highlight {
  color: #fff;
  font-weight: bold;
  font-size: 36px;
}

*/

- jsx에서 오브젝트로 만들어진 속성은 Camel로 표기 (하이픈 말고)

- javascript 변수에 css 담아서  사용

- css 파일 import 꼭 해야 함

 

 

 

실무 중심! FE 입문자를 위한 React 강의 | 인프런 - 인프런

인프런 | 강의를 모두 듣고 나면, 스스로 하나의 웹서비스를 개발할 수 있는 역량을 갖게 됩니다., 📣 공지사항• 해당 강의는 지식공유자의 질의응답이 지원되지 않는 강의인 점 참고부탁드립

www.inflearn.com

'Javascript > React' 카테고리의 다른 글

React 이벤트 핸들링  (2) 2025.01.09
React의 Life Cycle 이해 - Hooks  (5) 2025.01.08
컴포넌트, Props, State  (3) 2025.01.07
React란?  (0) 2025.01.06
React란?
- 사용자 인터페이스를 만들기 위한
Javascript 라이브러리

 

왜 React를 배워야 하는가?

- 트렌드다

- 편하다 -> SPA

 

어떻게 트렌드가 될 수 있었는가?

[전통적인 웹 서비스 방식]

- 브라우저는 웹서버에 A페이지와 관련된 리소스를 다운 받음 -> 링크를 통해 B페이지로 가면 -> 또다시 페이지 요청

- 서버에서 html를 만들고 내려줌.

- A->B 페이지 전환 시, 새로고침 됨.

[SPA 방식]

- Single Page Application

- 자바스크립트를 통해 현재 페이지에 html를 생성하는 방식.

- 서버에서 미리 a,b 리소스를 모두 받고, 브라우저에서 동적으로 화면을 그림.

- 자바스크립트에 의해 화면의 콘텐츠만 바뀌는 것 (<--> 새로고침)

- SPA 방식의 프레임워크/라이브러리: React, Vue, Angular 가 있음.

    - Angular(2010) -> React(2013) -> Angular2, Vue(2016)

 

React의 특징
- 컴포넌트 기반의 설계
- Virtual DOM
- CSR

React의 특징

1) 컴포넌트 기반의 설계

- 스스로 상태를 관리하는 캡슐화된 코드 조각

- 의미 단위로 컴포넌트를 구성

- 재사용성과 유지보수성 증가

- 부모, 자식 관계를 가짐.

2) Virtual DOM

- 실제 DOM의 복사본으로 SPA에서의 동적인 변화를 효율적으로 관리하기 위해 사용됨.

- javascript로 html을 동적으로 변경시킬 때, 브라우저가 DOM을 다시 재구축하고 화면을 그리게 되는 과정을 거침. (좀 느려서 잦은 DOM 변경은 웹서비스의 성능 문제 야기)

- 가상돔에서 미리 변경시켜놓고, 이것을 DOM에서 동기화시킴.

3) CSR

- client side rendering : 브라우저에서 화면을 렌더링함.

 

 

 

실무 중심! FE 입문자를 위한 React 강의 | 인프런 - 인프런

인프런 | 강의를 모두 듣고 나면, 스스로 하나의 웹서비스를 개발할 수 있는 역량을 갖게 됩니다., 📣 공지사항• 해당 강의는 지식공유자의 질의응답이 지원되지 않는 강의인 점 참고부탁드립

www.inflearn.com

 

'Javascript > React' 카테고리의 다른 글

React 이벤트 핸들링  (2) 2025.01.09
React의 Life Cycle 이해 - Hooks  (5) 2025.01.08
컴포넌트, Props, State  (3) 2025.01.07
React JSX (javascript xml)  (1) 2025.01.06

+ Recent posts