React 정리

HIHI JIN·2023년 2월 20일
0

react

목록 보기
4/19
post-thumbnail

리액트가 만들어진 배경

dom을 직접 건드리는 작업은 번거롭다.

React의 발상 : dom을 전부 날려버리고 다시 만들어서 보여주자

문제점 : 매번 이렇게 하게되면 다양한 문제가 발생

해결 : 메모리게 가상DOM을 만든다.
업데이트가 필요한 부분만 가상DOM으로 수정한다.
그 이후 REACT의 알고리즘을 통해 다른 부분을 감지하여 실제 DOM에 패치 시켜준다.

리액트 작업 환경

Node.js
자바스크립트 런타임인 Node.js 를 기반으로 만들어진 Webpack 과 Babel 같은 도구들을 사용하기 위해서 설치한다.
npm install
npx create-react-app my-app
cd my-app
npm start

리액트 컴포넌트

JSX : 리액트 컴포넌트에서 xml 형식의 값을 반환해는 것이다.

컴포넌트 : 일종의 UI 조각으로 쉽게 재사용 가능하다.

DOM 내부에 리액트 컴포넌트를 렌더링

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

JSX 기본 규칙

닫혀 있는 태그
태그는 꼭 닫혀있어야 한다.(Self Closing 태그)

<input />
//꼭 감싸져야 하는 태그
//두 개 이상의 태그는 무조건 하나의 태그로 감싸져야 한다.
import React from 'react';
import Hello from './Hello';
function App() {
  return (
    <> //리액트의 Fragment
      <Hello />
      <div>안녕히계세요</div>
    </>
  );
}
export default App;

JSX 안에 자바스크립트 값 사용하기
JSX 내부에 자바스크립트 변수를 보여줘야 할 때에는 {}으로 감싸서 보여준다

import React from 'react';
import Hello from './Hello';
function App() {
	const name = 'react';
  	return (
    	<>
      	<Hello />
      	<div>{name}</div>
      	</>
      );
}
export default App;
    )
}

style 과 className
1) JSX에서 인라인 스타일은 객체 형태로 작성해야한다.
2) background-color처럼 - 로 구분되어 있는 이름들은 backgroundColor처럼 camelCase 형태로 네이밍 해줘야 한다.
3) CSS class 를 설정 할 때에는 class= 가 아닌 className= 으로 설정해야 한다.

import React from 'react';
import Hello from './Hello';
import './App.css';
function App() {
  const name = 'react';
  const style = {
    backgroundColor: 'black',
    color: 'aqua',
    fontSize: 24, // 기본 단위 px
    padding: '1rem' // 다른 단위 사용 시 문자열로 설정
  }
  return (
    <>
      <Hello />
      <div style={style}>{name}</div>
      <div className="gray-box"></div>
    </>
  );
}
export default App;

주석
JSX 내부의 주석은 / * 이런 형태로 */ 작성한다.
열리는 태그 내부에서는 // 이런 형태로도 작성 가능하다.

props 를 통해 컴포넌트에게 값 전달하기

props
props는 properties의 줄임말로 어떠한 값을 컴포넌트에게 전달해줘햐 할때 사용한다.

비구조화 할당

//App.js
import React from 'react';
import Hello from './Hello';
function App() {
  return (
    <Hello name="react" color="red"/>
  );
}
export default App;


//Hello.js
import React from 'react';
function Hello({ color, name }){
	return <div style={{ color }}안녕하세요 { name }</div>
}
export default Hello;

defaultProps 로 기본값 설정
컴포넌트에 props 를 지정하지 않았을 때 기본적으로 사용 할 값을 설정하고 싶다면 컴포넌트에 defaultProps 라는 값을 설정하면 된다.

//Hello.js
import React from 'react';
function Hello({ color, name }) {
  return <div style={{ color }}>안녕하세요 {name}</div>
}
Hello.defaultProps = {
  name: '이름없음'
}
export default Hello;
//App.js
import React from 'react';
import Hello from './Hello';
function App() {
  return (
    <>
      <Hello name="react" color="red"/>
      <Hello color="pink"/> //'안녕하세요 이름없음'이 핑크색 글씨로 나온다.
    </>
  );
}
export default App;

props.children
컴포넌트 태그 사이에 넣은 값을 조회하고 싶을 땐, props.children 을 조회하면 된다.

//Wrapper.js
import React from 'react';
function Wrapper() {
  const style = {
    border: '2px solid black',
    padding: '16px',
  };
  return (
    <div style={style}>
    </div>
  )
}
export default Wrapper;
//App.js
import React from 'react';
import Hello from './Hello';
import Wrapper from './Wrapper';
function App() {
  return (
    <Wrapper>
      <Hello name="react" color="red"/>
      <Hello color="pink"/>
    </Wrapper>
  );
}export default App;

Wrapper 태그 내부에 Hello 컴포넌트 두개를 넣었는데, 브라우저를 확인하면 다음과 같이 Hello 컴포넌트들은 보여지지 않는다. 내부의 내용이 보여지게 하기 위해서는 Wrapper에서 props.children을 렌더링해주어야 한다.

//Wrapper.js
import React from 'react';
function Wrapper({ children }) {
  const style = {
    border: '2px solid black',
    padding: '16px',
  };
  return (
    <div style={style}>
      {children}
    </div>
  )
}
export default Wrapper;

조건부 렌더링

조건부 렌더링이란
조건부 렌더링이란, 특정 조건에 따라 다른 결과물을 렌더링 하는 것을 의미한다.

삼항 연산자, &&

<div style={{ color }}>
      { isSpecial ? <b>*</b> : null }
      안녕하세요 {name}
    </div>
<div style={{ color }}>
      {isSpecial && <b>*</b>}
      안녕하세요 {name}
    </div>

&&를 사용하면 첫번째로 나오는 false값을 반환하며 없다면 마지막 값을 반환한다.

useState 를 통해 컴포넌트에서 바뀌는 값 관리하기

이벤트 설정
리액트에서 엘리먼트에 이벤트를 설정해줄때에는 on이벤트이름={실행하고싶은함수} 형태로 설정해줘야 한다. 이벤트를 설정할 때에는 함수 타입의 값을 넣어주어야 한다.

동적인 값 끼얹기, useState
useState 라는 함수를 사용하면 컴포넌트에서 상태를 관리 할 수 있다.

카운터 만들기

//App.js
import React from "react";
import Counter from "./Counter";
function App() {
  return <Counter />;
}
export default App;


//Counter.js
//useState 함수 불러오가
import React, { useState } from "react";
function Counter() {
  //useState를 사용 할 때에는 상태의 기본값을 파라미터로 넣어서 호출.
  //함수를 호출하면 배열이 반환.
  //첫번째 원소는 현재 상태, 두번째 원소는 Setter 함수.
  const [number, setNumber] = useState(0);
  const onIncrease = () => {
    setNumber(number + 1);
  };
  const onDecrease = () => {
    setNumber(number - 1);
  };
  return (
    <div>
    //Setter 함수는 파라미터로 전달 받은 값을 최신 상태로 설정.
      <h1>{number}</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}
export default Counter;

input 상태 관리하기

input 태그 : 리액트에서 사용자가 입력 할 수 있는 태그이다.

input 창 만들기

//App.js
import React from 'react';
import InputSample from './InputSample';
function App() {
  return (
    <InputSample />
  );
}
export default App;


//InputSample.js
import React, { useState } from 'react';
function InputSample() {
  const [text, setText] = useState('');
  const onChange = (e) => {
    //
    setText(e.target.value);
  };
  const onReset = () => {
    setText('');
  };
  return (
    <div>
      <input onChange={onChange} value={text}  />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>: {text}</b>
      </div>
    </div>
  );
}
export default InputSample;

1) input의 onChange를 사용하면 이벤트 객체 e를 파라미터로 받아올 수 있다.
2) 이 객체의 e.target은 이벤트가 발생한 DOM을 가리킨다.
3) e.target.value를 조회하면 현재 input의 value값을 알 수 있다.

여러개의 input 상태 관리하기

input의 개수가 여러개일 때
1) input에 name을 설정하고 이벤트가 발생했을 때 이 값을 참조하는 것이다.
2) useState에서는 문자열이 아니라 객체 형태의 상태를 관리해야한다.

여러개의 input 창 만들기

//InputSample.js
import React, { useState } from 'react';
function InputSample() {
  const [inputs, setInputs] = useState({
    name: '',
    nickname: ''
  });
  const { name, nickname } = inputs; // 비구조화 할당을 통해 값 추출
  const onChange = (e) => {
    const { value, name } = e.target; // 우선 e.target 에서 name 과 value 를 추출
    setInputs({
      ...inputs, // 기존의 input 객체를 복사한 뒤
      [name]: value // name 키를 가진 값을 value 로 설정
    });
  };
  const onReset = () => {
    setInputs({
      name: '',
      nickname: '',
    })
  };
  return (
    <div>
      <input name="name" placeholder="이름" onChange={onChange} value={name} />
      <input name="nickname" placeholder="닉네임" onChange={onChange} value={nickname}/>
      <button onClick={onReset}>초기화</button>
      <div>
        <b>: </b>
        {name} ({nickname})
      </div>
    </div>
  );
}
export default InputSample;

1) 리액트에서 객체를 업데이트하게 될 때에는 기존 객체를 직접 수정하면 안되고, 새로운 객체를 만들어서, 새 객체에 변화를 주어야 한다.

setInputs({
  ...inputs,
  [name]: value
});

불변성을 지킨다
1) 불변성을 지켜야만 리액트 컴포넌트에서 상태가 업데이트가 됐음을 감지 할 수 있고 이에 따라 필요한 리덴더링이 진행된다.
2) 컴포넌트 업데이트 성능 최적화를 제대로 할 수 있다.

useRef 로 특정 DOM 선택하기

useRef
1) 리액트를 사용하는 프로젝트에서도 가끔씩 DOM 을 직접 선택해야 하는 상황이 발생 할 때가 있다(특정 엘리먼트의 크기를 가져와야 한다던지, 스크롤바 위치를 가져오거나 설정해야된다던지, 또는 포커스를 설정해줘야된다던지 등)
2) 그럴 때 useRef 라는 Hook 함수를 사용한다.

초기화 버튼 클릭했을 때 이름 input 에 포커스가 잡히는 기능 구현하기

import React, { useState, useRef } from 'react';
function InputSample() {
  const [inputs, setInputs] = useState({
    name: '',
    nickname: ''
  });
  const nameInput = useRef();
  const { name, nickname } = inputs; // 비구조화 할당을 통해 값 추출
  const onChange = e => {
    const { value, name } = e.target; // 우선 e.target 에서 name 과 value 를 추출
    setInputs({
      ...inputs, // 기존의 input 객체를 복사한 뒤
      [name]: value // name 키를 가진 값을 value 로 설정
    });
  };
  const onReset = () => {
    setInputs({
      name: '',
      nickname: ''
    });
    nameInput.current.focus();
  }; //input에 포커스를 하는 focus() DOM API를 호출해주었다.
  return (
    <div>
      <input
        name="name"
        placeholder="이름"
        onChange={onChange}
        value={name}
        ref={nameInput}
      />
      <input
        name="nickname"
        placeholder="닉네임"
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>: </b>
        {name} ({nickname})
      </div>
    </div>
  );
}
export default InputSample;

1) useRef()를 사용하여 Ref 객체를 만들고,
2) 이 객체를 우리가 선택하고 싶은 DOM에 ref 값으로 설정해준다.
3) 그러면, Ref 객체의 .current 값은 우리가 원하는 DOM 을 가르키게 됩니다.

배열 렌더링하기

동적인 배열 렌더링
동적인 배열을 렌더링해야 할 때에는 자바스크립트 배열의 내장함수 map() 을 사용한다.

Map에서 Key가 필요한 이유
1)리액트에서 배열을 렌더링 할 때에는 key 라는 props 를 설정해야 한다. key 값은 각 원소들마다 가지고 있는 고유값으로 설정을 해야한다.
2) Map에 key 값이없다면 중간의 값이 바뀌었을때 그 하위 값들이 전부 변한다. key값을 사용한다면 key를 이용해 중간의 값을 추가하게 된다.

배열을 렌더링하기

//UserList.js
import React from 'react';
function User({ user }) {
  return (
    <div>
      <b>{user.username}</b> <span>({user.email})</span>
    </div>
  );
}
function UserList() {
  const users = [
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com'
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com'
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com'
    }
  ];
  return (
    <div>
      {users.map(user => (
        <User user={user} key={user.id} />
      ))}
    </div>
  );
}
export default UserList;
profile
신입 프론트엔드 웹 개발자입니다.

0개의 댓글