React.js 입문
1. React Component
- Javascript 함수가 html 태그들을 반환하도록 설정할 수 있음
- 이렇게 html 태그들을 반환하는 함수를 Component
- Class를 통해서 Component를 만들 수 있지만, 코드의 양이 많아지므로 사용하지 않음
- 함수형 Component의 첫글자는 대문자

- Header라는 함수형 Component를 생성
- 원하는 위치에 Component를 배치하면 렌더링이 돼서 화면에 출력
- 여기서 부모 Component는 App, 자식 Component는 Header


- Component들을 한 파일에 작성하는 것보다 기능별로 모듈로 나눠서 작성하는 게 더 좋음
- components 폴더를 만들고 이 안에 App.jsx를 제외한 component들을 넣어줌
- components 폴더 안에 Header.jsx 파일을 작성
- ES 모듈 시스템으로 Header.jsx에서는 export default, App.jsx에서는 import Header from './components/Header.jsx'를 사용함

- Main.jsx, Footer.jsx도 추가해서 렌더링한 결과
2. JSX로 UI 표현하기
JSX

- Javascript Extension으로 Javascript의 확장된 문법
- Javascript와 html을 혼용해서 사용 가능

JSX 사용시 주의사항
- {}안에는 Javascript 표현식만 가능
- 숫자, 문자열, 배열의 값만 렌더링 가능
- 모든 태그는 닫혀있어야 함
- 최상위 태그는 반드시 하나

JSX로 스타일 구현

- 요소에 직접 스타일 속성 지정
- 객체 형태로 전달
- 속성명은 CSS 스타일과 다르게 -쓰지 않고 camelCase로 작성
- 속성값은 문자열로 전달
- 가독성이 떨어질 수 있음

3. Props로 데이터 전달하기

- React에서는 페이지를 Component라는 단위로 나누어서 레고를 조립하듯 개발함

- 위 사진과 같이 네이버 헤더의 여러 버튼들을 구현하고 싶다고 한다면, 버튼 Component를 만들어서 세부 내용만 다르게 렌더링하면 됨
- 이렇게 세부 내용을 다르게 렌더링하기 위해서는 값을 전달해야함
- 부모 Component가 자식 Component에게 전달된 원하는 값을 Props라고 함

- 자식 Component에게 props를 전달해 주면, 이 값들은 객체로 묶여서 자식 Component의 매개변수로 제공됨
- 매개변수는 객체로 제공이 되고, 해당 객체는 전달한 props값들이 프로퍼티로 하나씩 들어있음
- Button Component에 text를 props로 전달하면 다르게 구현 가능

- 위처럼 없는 props를 사용해야하는 경우가 있으면 오류가 발생함
- color라는 프로퍼티가 없기 때문에 오류 발생

- 이 문제를 해결하기 위해서 defaultProps라는 것을 사용하면 해결 가능
- color의 기본값이 black이기 때문에 오류발생 안함

- props는 객체 형태로 묶여오니까 구조분해할당으로 꺼내면 더 쉽게 사용 가능

- 부모에서 자식에게 전달할 props가 많으면, 미리 객체로 묶고 spread연산자를 사용하면 편함

- Props를 통해서 html, React Component도 전달가능
- 자식요소들은 children이라는 프로퍼티로 전달됨
4. 이벤트 처리하기
- 사용자들의 모든 행동을 이벤트라고 함
- 이벤트 핸들링이란 웹에서 이벤트가 발생했을 때 처리해주는 것

- 버튼을 클릭했을 때 해당 text가 콘솔에 출력되는 이벤트는 onClickButton 함수를 먼저 정의하고, 클릭 이벤트 핸들러로 onClick={onClickButton} 해주면 됨
- 함수의 이름만 전달하면 됨
이벤트 객체

- 발생한 이벤트는 이벤트 핸들러 함수를 호출하면서 호출된 이벤트 핸들러 함수에 매개변수로 이벤트 객체를 제공
- onClickButton에 매개변수로 e를 적어서 콘솔에 찍어보면 SystheticBaseEvent라는 것이 출력됨

- SystheticBaseEvent : 합성 이벤트
- 모든 웹 브라우저의 이벤트 객체를 하나로 통일한 형태
- 브라우저마다 이벤트 객체가 다른데, 이때 발생하는 cross browsing issue를 해결해줌
- 여러 브라우저들의 규격을 참고해서 하나의 통일된 규격으로 이벤트 객체를 포매팅해줌
- 모든 브라우저에서 사용가능한 이벤트 객체
5. State 상태 관리하기

- State는 말그대로 상태
- 현재 상태에 따라 다른 모양, 동작을 함
- React의 Component들도 이러한 State를 가질 수 있음
- 즉 Component의 현재 상태를 갖는 변수

- State의 값에 따라 렌더링되는 UI가 달라짐
- State의 값이 달라질 때 Component가 다시 렌더링되는 과정을 Re-Render / Re-Rendering이라고 함

- 하나의 Component에 여러 개의 State를 가질 수 있음

- State를 관리하기 위해서는 React가 제공하는 useState라는 내장함수를 import 해야함
- useState라는 함수는 배열을 반환하는데, 첫번째 요소는 초기 state의 값, 두번째 요소는 state값을 변화시키는 상태 변화 함수가 들어있음
- 따라서 구조분해할당으로 처음 state를 정의할 때, [상태, 상태변화함수]로 정의함

- 버튼을 클릭할 때 count값을 1씩 증가하는 방법
- 버튼이 클릭되면 setCount함수가 count를 1씩 증가시키고, React가 내부적으로 count 값이 변경되었다는 것을 인식하고 리렌더함
왜 State를 꼭 써야하지?
- Javascript 변수를 설정해서 클릭 이벤트가 발생했을 때도 똑같이 구현할 수 있지 않을까? -> 리렌더링 과정이 안일어남
- React에서는 state값이 변화할 때만 리렌더링 과정이 일어남
6. State를 Props로 전달하기

- 자신이 갖는 state가 변경되지 않아도, 부모로부터 받는 props 값이 변경되면 리렌더링 과정 발생
- 자신의 State, Props가 변경될 때 + 부모의 State가 변경될 때 리렌더링 됨
- 위와 같은 예시가 있을 때, count의 값만 바뀌어도 Bulb Component도 리렌더링 됨

- 따라서 관련 없는 Component들을 분리하는 것이 좋음
7. State로 사용자 입력 관리하기
이름, 생년월일, 국적, 자기소개를 받는 간단한 입력
import { useState } from 'react';
const Register = () => {
const [name, setName] = useState('이름');
const [birth, setBirth] = useState('');
const [country, setCountry] = useState('');
const [bio, setBio] = useState('');
const onChangeName = (e) => {
setName(e.target.value);
};
const onChangeBirth = (e) => {
setBirth(e.target.value);
};
const onChangeCountry = (e) => {
setCountry(e.target.value);
};
const onChangeBio = (e) => {
setBio(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName} placeholder={'이름'} />
</div>
<div>
<input value={birth} onChange={onChangeBirth} type="date" />
</div>
<div>
<select value={country} onChange={onChangeCountry}>
<option></option>
<option value={'kr'}>한국</option>
<option value={'us'}>미국</option>
<option value={'uk'}>영국</option>
</select>
{country}
</div>
<div>
<textarea value={bio} onChange={onChangeBio} />
</div>
</div>
);
};
export default Register;

위의 예시를 효율적으로 개선
import { useState } from 'react';
const Register = () => {
const [input, setInput] = useState({
name: '',
birth: '',
country: '',
bio: '',
});
const onChange = (e) => {
setInput({
...input,
[e.target.name]: e.target.value,
});
};
return (
<div>
<div>
<input name="name" value={input.name} onChange={onChange} placeholder={'이름'} />
</div>
<div>
<input name="birth" value={input.birth} onChange={onChange} type="date" />
</div>
<div>
<select name="country" value={input.country} onChange={onChange}>
<option></option>
<option value={'kr'}>한국</option>
<option value={'us'}>미국</option>
<option value={'uk'}>영국</option>
</select>
</div>
<div>
<textarea name="bio" value={input.bio} onChange={onChange} />
</div>
</div>
);
};
export default Register;

- 많고 복잡하게 상태관리를 해야하면 하나의 객체로 묶음
- 많고 복잡한 이벤트 핸들러들을 하나의 통합된 이벤트 핸들러로 묶음
8. useRef - Component의 변수 생성하기
- useRef는 새로운 Reference 객체를 생성하는 기능
- 값이 변경될 때 useState는 리렌더링되지만, useRef는 리렌더링되지 않음
- const refObj = useRef(0);로 사용

- useRef는 처음만 리렌더링되고, current 값이 변경되어도 리렌더링되지 않음
- 레퍼런스 오브젝트는 렌더링에 영향을 미치지 않는 변수에 사용함
- javascript 코드로 let 같은 키워드를 사용하면, 리렌더링될 때 같이 초기화되는 문제가 발생하거나, 외부에 선언한 경우 Component를 여러 번 사용할 때 문제가 발생할 수 있음 따라서 useRef를 사용해야 함
9. React Hooks

- React Hooks란 클래스형 Component의 기능을 함수형 Component에서도 사용할 수 있도록 도와주는 메서드
- 예전에는 문법이 복잡한 클래스형 Component에서만 모든 기능을 사용할 수 있었음
- useState, useRef 둘 다 React Hooks
- React Hooks 앞에는 use라는 말이 앞에 옴
- Component 내부에서만 호출할 수 있고, 조건문, 반복문 내부에서는 호출 불가
- use를 앞에 붙여서 custom Hook을 만들 수 있음

![업로드중..]()
- input을 관리하는 useInput hook 예시
사진 및 참고 출처 - 한입 크기로 잘라먹는 리액트