[React] 리액트 입문_복습중(-ing)

fejigu·2022년 10월 3일
1

React

목록 보기
15/16
post-thumbnail

월요일 연휴 맞이 리액트 다시 복습하는 시간 가지기


1. 리액트는 어쩌다 만들어졌을까?

배경

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

React의 발상

dom을 전부 날려버리고 다시 만들어서 보여주자

문제점

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

해결

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


2. 작업 환경 준비

Node.js

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

Yarn

조금 개선된 버전의 npm, 프로젝트에서 사용되는 라이브러리를 설치하고 해당 라이브러리들의 버전 관리를 하게 될 때 사용한다.

코드 에디터

주로 VSCode를 사용한다.


3. 리액트 컴포넌트

JSX

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

컴포넌트

일종의 UI 조각으로 쉽게 재사용 가능하다.

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

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

4.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 내부의 주석은 {/* 이런 형태로 */} 작성한다.
열리는 태그 내부에서는 // 이런 형태로도 작성 가능하다.


5.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;


6. 조건부 렌더링

조건부 렌더링이란

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

삼항 연산자, &&

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

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


7. 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;

8. 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값을 알 수 있다.


9. 여러개의 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) 컴포넌트 업데이트 성능 최적화를 제대로 할 수 있다.


10. 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 을 가르키게 됩니다.


11. 배열 렌더링하기

동적인 배열 렌더링

동적인 배열을 렌더링해야 할 때에는 자바스크립트 배열의 내장함수 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개의 댓글