React 간단 정리

hyeonyohwan·2021년 4월 5일
0
post-custom-banner

React란?

  • 사용자 인터페이스를 구축하기 위한 선언적이고 효율적이며 유연한 JavaScript 라이브러리이다. '컴포넌트' 라고 불리는 작고 고립된 코드의 파편을 이용하여 복잡한 UI를 구성하도록 돕는다. React에서는 JSX라 불리는 JavaScript 확장 문법을 자주 사용한다.

특징

  • JSX - JSX는 JavaScript의 Syntax 확장이다. JSX를 사용하는것이 필수는 아니지만, 사용하는것이 권장된다.
  • Components - React는 전부 Component에 대한 것이다. React 개발을 할땐 모든것을 Component로서 생각해야 한다. ( Component는 독립적인 기능을 수행하는 소프트웨어 모델)
  • 단일방향 (Unidirectional) 데이터 흐름 & Flux - React에선 데이터가 단일방향으로만 흐른다. 데이터 흐름을 단방향으로 제한함으로서 데이터를 추적하기 쉽고 디버깅을 쉽게 해준다. Flux는 데이터가 단일방향으로 흐르는것을 유지해주는 패턴이다.

장점

  • React는 JavaScript 객체 형태의 Virtual DOM 을 사용하여 어플리케이션의 성능을 향상시킴 (JavaScript Virtual DOM 처리가 실제 DOM 보다 빠르기 때문)
  • 서버 & 클라이언트 사이드 렌더링 지원을 통해 브라우저측의 초기 렌더링 딜레이를 줄이고, SEO 호환도 가능해짐
  • Component 의 가독성이 매우 높고 간단하여 쉬운 유지보수, 간편한 UI 수정 및 재사용 용이
  • React는 프레임워크가 아닌 라이브러리기 때문에 다른 프레임워크와 혼용 가능

단점

  • VIEW ONLY , VIEW 이외의 기능은 써드파티 라이브러리(Third party library, 패키지, 모듈로 불리기도함)를 이용하거나 직접 구현해야함
  • IE8 이하 지원하지 않음 (IE8 이하 버전을 지원해야 할 경우 v0.14 버전을 사용 해야함)
  • React는 inline-template 과 JSX 를 사용하는데, 일부 개발자들에게는 적응이 안 될 수 있음

JSX란

const element = <h1> Hello, world!</h1>;

위와 같은 코드를 예로 들 수 있다.

JSX 에서는 JavaScript 와 약간 다른 속성이름을 사용하는데 그 중 예를 들자면 className 이 있다. (JavsScript 에서는 class)

엘리먼트(Element)

  • 엘리먼트는 React 앱의 가장 작은 단위이다.
  • 브라우저 DOM 엘리먼트와 달리 React 엘리먼트는 일반 객체이며 쉽게 생성할 수 있다. React DOM 은 React 엘리먼트와 일치하도록 DOM을 업데이트한다.
  • 모든 엘리먼트는 React DOM에서 관리하기 때문에 이것을 루트 DOM 노드라고 부른다.
  • React 엘리먼트는 불변객체이다. 엘리먼트를 생성한 이후에는 해당 엘리먼트의 자식이나 속성을 변경할 수 없다.
  • ex )
const element = <h1> Hello, world </h1>;
ReactDOM.render(element, document.getElementById('root'));

렌더링(Rendering)

  • HTML 요소 또는 React 요소 등의 코드가 눈으로 볼 수 있도록 그려지는 것이다.

리액트 생명주기(React LifeCycle)

  • Initialization -> Mounting -> Updation -> Unmounting

Initialization - 초기화 / Mount - React에서 DOM 혹은 페이지에 올라갈 때 / Update - props나 state가 변경되었을 때 / Unmount - React에서 DOM 혹은 페이지에 내려갈 때

Props - 컴포넌트끼리 값을 전달하는 수단으로, 부모 컴포넌트가 하위 컴포넌트에게 주는 값이다. props는 사용하는 것은 가능하나 props 자체를 하위 컴포넌트가 변경 시키는 행위는 할 수 없다.

State - 각 컴포넌트가 가지고 있는 개별적인 상태값이다. 클래스형 컴포넌트를 작성할때는 해당 클래스 내부 맨 위쪽에 작성하는 것이 일반적이며 state는 객체이다.

DOM(Document Object Model) - HTML 단위 하나하나를 객체로 생각한 모델(document, html, body, div, ul ...)

Ref - 리액트에서 DOM에 이름을 다는 방법

ex) <input ref={(ref) => this.inputName=ref}

함수 컴포넌트

function Welcome(props){
	return <h1> Hello, {props.name} </h1>;
}

클래스 컴포넌트

class Welcome extends React.Component{
	render(){
		return <h1> Hello, {this.props.name} </h1>;
	}
}

React의 엄격한 규칙 - 모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수처럼 동작해야 한다.

function sum(a, b){
	return a + b;
} // 이런 함수들을 순수함수라고 호칭한다. 입력값을 바꾸려 하지 않고 항상 동일한 입력값에 대해 동일한 결과를 반환하기 때문이다.
function withdraw(account, amount){
	account.total -= amount;
} // 이런 함수들은 순수함수가 아니다. 자신의 입력값을 변경하기 때문이다.

큰 컴포넌트는 여러 개의 작은 컴포넌트로 나눠 재사용하기 용이하게 만드는 것이 좋다.

이벤트 처리

  • HTML 에서는 아래와 같이
<button onclick="activateLasers()">
	Activate Lasers
</button>
  • React 에서는 아래와 같다.
<button onClick={activateLasers}>
	Activate Lasers
</button>
  • React 에서 이벤트의 기본 동작을 방지하는 방법은 아래와 같다.
function ActionLink(){
	function handleClick(event){
		event.preventDefault();	// 현재 이벤트의 기본 동작을 중지하는 것이다.
		console.log('The link was clicked');
	}
	
	return (
		<a href = "#" onClick={handleClick}>
			Click me
		</a>
	);
}

리스트와 Key

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) => {
	<li>{number}</li>
});

Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다. Key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 한다.

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) => {
	<li key={number.toString()}>
		{number}
	</li>
});

제어 컴포넌트

input, textarea, select 와 같은 폼 엘리먼트는 일방적으로 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트한다. React에서는 변경할 수 있는 state가 일반적으로 컴포넌트의 state에 유지되며 setState()에 의해 업데이트된다.

(자세한 내용은 React 공식 문서 참고)

props vs state

  • props와 state 는 일반 JavaScript 객체이다. 두 객체 모두 렌더링 결과물에 영향을 주는 정보를 갖고 있는데, 한 가지 중요한 방식에서 차이가 있다. props는 함수 매개변수처럼 컴포넌트에 전달되는 반면 state는 함수 내에 선언된 변수처럼 컴포넌트 안에서 관리된다.

[ React Hook ]

  • 복잡한 class 없이 React 기능들을 사용하는 방법이다. (함수형)

1. useState

  • useState는 함수형 컴포넌트에서 state를 가질 수 있게 하는 Hook이다.
  • useState 훅이 반환하는 배열의 첫번째 요소는 상태값이며, 두번째 요소는 상태값 변경 함수이다.
  • 상태값 변경 함수가 호출되면 컴포넌트는 리렌더링되며 리렌더링 과정에서 자식 컴포넌트도 같이 렌더링된다.
  • 참조타입을 상태값으로 사용하는 경우, 얕은비교/깊은비교에 주의해야 한다. (얕은비교로 처리한다)
  • 리액트는 가능하다면, 상태값 변경을 배치(batch)로 처리(🙏주의! 리액트 외부에서 관리되는 이벤트 처리 함수의 경우에는 상태값 변경이 배치(batch)로 처리되지 않음!)
const [state, setState] = useState(initialState);		// state -> 현재 상태, setState -> 상태 설정 함수
function App(){
// useState를 사용하여 count라는 state를 생성하여 초기값은 0으로 지정
	const [count, setCount] = useState(0);
	const add = () => {setCount(count + 1);};	// setCount로 state값 변경
	const min = () => {setCount(count - 1);};
  
  const addDouble = () => {
    setCount(prevState => prevState + 1);
    setCount(prevState => prevState + 1);         
	}		// 이전 상태값을 매개변수로 받지 않고 setCount(count + 1)을 두번 실행하는 방식으로 하면 상태값 변경 함수의 비동기식 동작으로 인해 1만 증가한다.
	return(
		<div>
			<p>Current COUNT: {count}</p>
				<button onClick={add}>+</button>
			<button onClick={min}>-</button>
		</div>
	);
}

2. useEffect

  • useEffect는 리액트 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook이다.
  • 부수효과 함수 (API호출, 이벤트 처리 등)에 사용된다.
  • useEffect 훅은 부수효과 함수와 의존성 배열을 인자로 받는다.
  • 의존성 배열에 값을 입력하면 배열의 값이 변경되는 경우에만 실행이 된다.
  • 의존성 배열을 주지 않는 경우, 컴포넌트가 렌더링할 때마다 실행이 된다.
useEffect(() => {
	console.log('첫 렌더링만 실행~!!');
},[]);		// useEffect를 마운트될 때만 실행하고 싶을 경우에는 두번째 파라미터에 비어있는 배열을 넣어주면 된다. (처음에만 발생)
function App(){
	const [count, setCount] = useState(0);
	const add = () => {setCount(count + 1);}
	const min = () => {setCount(count - 1);}
	useEffect(() => {
		console.log('렌더링할 때마다 실행~!!');
	});
	return(
		<div>
			<p>Current COUNT: {count}</p>
				<button onClick={add}>+</button>
			<button onClick={min}>-</button>
		</div>
	);
}
export default App;

3. useRef

  • useRef를 사용하여 ref를 설정하면 useRef를 통해 만든 객체 안의 current 값이 실제 엘리먼트를 가르키게 된다. (직접 DOM 요소에 접근해야할 때 useRef 훅을 사용하여 DOM 요소에 직접 접근 가능)
  • useRef 훅이 반환하는 ref 객체를 이용해서 자식 요소에 접근 가능

이벤트를 발생했을 때 event.target.value로 해당 값을 가져오는 방법을 useRef를 사용하여 값을 가져올 수 있다.

function App(){
	const textRef = useRef();
	const changeEvent = (event) => {
		let eventValue = event.target.value;
		let refValue = textRef.current.value;
		console.log(eventValue, refValue);
	}
	return (
		<div>
			<input type="text" ref={textRef} onChange={changeEvent}></input>
		</div>
	);
}
export default App;

4. useMemo

  • 컴퓨터 프로그램이 동일한 계산을 반복해야할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술
  • 이전 값을 기억해서 성능을 최적화하는 기술
  • 계산량이 많은 함수의 반환값을 재활용하는 용도로 사용한다.
import React, {useState, useMemo} from 'react';

export default function App() {

  const [number, setNumber] = useState(1);

  const memoNumber = useMemo(()=> number * 100, [number]);

  return (
    <div>
      <div style={{boarder : '1px dotted skyblue'}}>
        <h2>useMemo</h2>
        <p>
          useMemo 훅은 계산량이 많은 함수의 반환값을 재활용하는 용도로 사용
        </p>
        <p>
          {`memoNumber : ${memoNumber}`}
        </p>
      </div>
    </div>
  );
}
  • 첫 번째 인자로 함수를 받는다.
  • 두 번째 인자로 의존성 배열을 받는다. 의존성 배열이 변경되지 않으면 이전에 반환된 값을 재사용

5. useCallback

  • 리액트의 렌더링 성능을 위해 제공되는 훅으로, 컴포넌트가 렌더링될 때마다 새로운 함수를 생성해서 자식 컴포넌트의 속성값으로 입력하는 경우가 많다.
import React, { useState, useEffect, useCallback } from "react"

function Profile({ userId }) {
  const [user, setUser] = useState(null)

  const fetchUser = useCallback(
    () =>
      fetch(`https://your-api.com/users/${userId}`)
        .then((response) => response.json())
        .then(({ user }) => user),
    [userId]
  )

  useEffect(() => {
    fetchUser().then((user) => setUser(user))
  }, [fetchUser])

  // ...
}
  • 첫 번째 인자로 함수를 받는다.
  • 두 번째 인자로 의존성 배열을 받아 의존성 배열이 변경되지 않으면 이전에 생성한 함수를 재사용한다.

useMemo는 상태값을 반환하고, useCallback은 함수를 반환한다는 차이점이 있다.

6. useContext

  • context 객체를 받아 그 context의 연재 값을 반환한다. context의 현재 값은 트리 안에서 이 Hook을 호출하는 컴포넌트에 가장 가까이에 있는 prop에 의해 결정된다.

const value = useContext(MyContext);

7. useReducer

  • useState의 대체 함수이다. (state, action) => newState의 형태로 reducer를 받고 dispatch 메소드와 짝의 형태로 현재 state를 반환한다.
  • 가장 간단하게 사용하는 방법으로는 초기 state를 두 번째 인자로 전달하는 것이다.

const [state, dispatch] = useReducer(reducer, initialArg, init);


리액트에서 컴포넌트를 만들려면 React.Component 클래스를 상속하고, 데이터는 꼭 this.state에 담아두어야 하며 render() 함수에 JSX 문법을 이용하여 데이터를 어떻게 UI로 표기할건지 정의를 하여 만들어야한다. (리액트 규칙)

state에 있는 상태를 변경하기 위해서는 setState() 를 사용해야 한다. 리액트의 state를 직접적으로 수정하는 것은 좋지 않으므로 꼭 불변성을 유지하는 것이 좋다.

<공부하려고 여기저기서 모아온 React 정리>

출처 - 리액트 공식문서 // https://velog.io/@vvvvwvvvv // https://velog.io/@edie_ko // https://chanhuiseok.github.io // https://medium.com/wasd // https://hokeydokey.tistory.com/53 // https://www.daleseo.com/react-hooks-use-callback/ // https://velog.io/@katanazero86/react-hooks

profile
웹 프론트엔드 개발자입니다.
post-custom-banner

0개의 댓글