본문 바로가기

WINK-(Web & App)/React.js 스터디

[2024-2 React.js 스터디] 윤아영 #1주차

반응형

1. 리액트가 만들어진 계기

어떠한 상태가 바뀌었을때, 그 상태에 따라 DOM 을 어떻게 업데이트 할 지 규칙을 정하면 코드가 복잡해지는 문제가 있다.

리액트는 상태가 업데이트 되면, 업데이트가 필요한 곳의 UI 를 Virtual DOM 을 통해서 렌더링하고 실제 브라우저에 보여지고 있는 DOM 과 비교를 한 후, 차이가 있는 곳을 감지하여 이를 실제 DOM 에 패치시키는 방법으로 이 문제를 해결하였다.


2. 새 프로젝트 만들기

터미널에서 다음 명령어를 실행한다.

$ npx create-react-app begin-react #(프로젝트명)

 

해당 디렉터리에 들어간 다음 명령어를 실행한다.

$ yarn start # 혹은 npm start

3. 리액트 컴포넌트 만들기

리액트 컴포넌트를 만들 때에는 다음 코드가 필요하다.

import React from 'react';

 

컴포넌트를 내보낼 때에는 코드의 최하단에 다음 코드를 작성한다. 이렇게 하면 다른 컴포넌트에서 사용할 수 있게 된다.

export default Hello; # Hello는 컴포넌트 이름이다.

 

이렇게 만든 컴포넌트는 다음과 같은 방법으로 사용할 수 있으며, 재사용이 가능하다.

<Hello />

4. JSX의 기본 규칙

  1. 태그는 꼭 닫혀있어야 한다.
  2. 두 개 이상의 태그는 무조건 하나의 태그로 감싸져있어야 한다. 이 때 꼭 div 태그가 아니어도 되며, Fragment(<></>) 로 감싸주  어도 된다.
  3. JSX 내부에 자바스크립트 변수를 보여줘야 할 때에는 {} 으로 감싸서 보여준다.
  4. style을 설정할 때 인라인 스타일은 객체 형태로 작성을 해야 하며, background-color 처럼 - 로 구분되어 있는 이름들은 backgroundColor 처럼 camelCase 형태로 네이밍 해주어야 한다.
  5. CSS class 를 설정 할 때에는 class= 가 아닌 className= 으로 설정을 해주어야 한다.
  6. JSX 내부의 주석은 {/* 이런 형태로 */} 작성해야하며, 열리는 태그 내에서는 // 이런 형태로 작성할 수도 있다.

5. props

props 는 properties 의 줄임말이며 우리가 어떠한 값을 컴포넌트에게 전달해줘야 할 때 사용한다.

 

Hello 컴포넌트에 name 이라는 값을 전달하고 싶다면 다음과 같이 사용하면 된다.

#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(props) {
  return <div style={{ color: props.color }}>안녕하세요 {props.name}</div>
}

export default Hello;

 

이 때 함수의 파라미터에서 비구조화 할당(혹은 구조 분해) 문법을 사용하면 조금 더 코드를 간결하게 작성 할 수 있다.

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

function Hello({ color, name }) {
  return <div style={{ color }}>안녕하세요 {name}</div>
}

Hello.defaultProps = {
  name: '이름없음'
}

 

컴포넌트 태그 사이에 넣은 값을 조회하고 싶을 때에는 props.children을 사용한다.

다음 코드에서는 children을 사용하면 <Wrapper></Wrapper> 사이의 값을 사용할 수 있다.

# 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;
<Wrapper>
	<Hello name="react" color="red"/>
	<Hello color="pink"/>
</Wrapper>

6. 조건부 렌더링

다음 코드들은 isSpecial 값이 true일 때 <b>*</b> 를 보여준다.

{ isSpecial ? <b>*</b> : null }
{isSpecial && <b>*</b>}

 

다음 코드와 같이 props을 사용할 때 props 이름만 작성하면 자동으로 true로 설정된다.

<Hello name="react" color="red" isSpecial />

7. useState

useState를 이용하여 컴포넌트에서 상태를 관리 할 수 있다.

 

useState 정의 방법

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

 

다음 방법을 통해 number 값을 바꿀 수 있다.

setNumber(number + 1);
setNumber(prevNumber => prevNumber + 1);

8. input 상태 관리

다음 방법을 통해 input 상태 관리를 할 수 있다.

const [text, setText] = useState('');

  const onChange = (e) => {
    setText(e.target.value);
  };

  const onReset = () => {
    setText('');
  };

 

input 태그의 value 값을 설정해주어 input 입력값이 바뀌었을 때 업데이트를 할 수 있다.

<input onChange={onChange} value={text} />
<button onClick={onReset}>초기화</button>

 

여러개의 input을 관리할 때에는 객체 형태를 사용하는 것이 좋다.

const [inputs, setInputs] = useState({
    name: '',
    nickname: ''
  });
<input name="name" placeholder="이름" onChange={onChange} value={name} />
<input name="nickname" placeholder="닉네임" onChange={onChange} value={nickname}/>
setInputs({
      ...inputs, // 기존의 input 객체를 복사한 뒤
      [name]: value // name 키를 가진 값을 value 로 설정
    });

9. useRef

1. 특정 DOM 선택

 

useRef를 사용하여 특정 DOM을 선택할 수 있다.

다음 방법으로 onReset 함수 실행시 이름 input에 focus를 할 수 있다.

const nameInput = useRef();
const onReset = () => {
    setInputs({
      name: '',
      nickname: ''
    });
    nameInput.current.focus();
  };
<input
	name="name"
	onChange={onChange}
	value={name}
	ref={nameInput}
      />

 

 

2. 컴포넌트 안 변수 만들기

 

useRef 로 관리하는 변수는 값이 바뀐다고 해서 컴포넌트가 리렌더링되지 않는다.

리액트 컴포넌트에서의 상태는 상태를 바꾸는 함수를 호출하고 나서 그 다음 렌더링 이후로 업데이트 된 상태를 조회 할 수 있는 반면, useRef 로 관리하고 있는 변수는 설정 후 바로 조회 할 수 있다.

const nextId = useRef(4);
  const onCreate = () => {
    // 배열에 항목 추가하는 로직

    nextId.current += 1;
  };

 

이 값을 수정 할때에는 .current 값을 수정하면 되고 조회 할 때에는 .current 를 조회하면 된다.


10. 배열 렌더링

map() 함수를 이용하여 배열을 간단한 방법으로 렌더링할 수 있다.

<div>
  {users.map((user, index) => (
    <User user={user} key={index} />
  ))}
</div>

 

배열을 렌더링할 때는 고유한 key값이 있어야 한다.


11. 배열

1. 항목 추가

const [users, setUsers] = useState([
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com'
    },
 ]);

 

방법1) spread 이용

const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers([...users, user]);

 

방법2) concat 이용

setUsers(users.concat(user));

 

2. 항목 제거

  const onRemove = id => {
    // user.id 가 파라미터로 일치하지 않는 원소만 추출해서 새로운 배열을 만듬
    // = user.id 가 id 인 것을 제거함
    setUsers(users.filter(user => user.id !== id));
  };

 

3. 항목 수정

const [users, setUsers] = useState([
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com',
      active: true
    }
 ]);
const onToggle = id => {
    setUsers(
      users.map(user =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  };

 

배열의 불변성을 유지하면서 배열을 업데이트 할 때에 map 함수를 사용 할 수 있다.

 

 

참고: https://react.vlpt.us/

반응형