React.js란?
React.js는 애플리케이션에서 UI를 구현하는데 사용되는 JS 프레임워크
특징
- 컴포넌트 기반
- Virtual DOM 사용
- 단방향 데이터 바인딩 사용
- build가 쉬운 SPA 프레임워크
- 심플하지만 강력
- 선언적
- Server-side 지원
참고
- react 자체는 라이브러리이지만 react 생태계에서는 프레임워크라고 볼 수 있음
- react(페이스북에서 만듬), vue, angular, svelte 등 모두 SingPageApplication을 만들기 위한 라이브러리/프레임워크
- 실무에서는 webpack, vite, babel 등으로 빌드 / 최종 결과물은 결국 html, css, js
(babel이 JSX 코드 -> React.createElement 로 바꿔줌)
- react도 결국 js다.
- react는 데이터 중심으로 움직인다.
장점
- 데이터와 화면 일치 문제해결(데이터를 바꾸면 화면이 바뀌어야 함)
- 화면의 깜박임 해결
단점
v17 vs v18
React 입문 강의
https://www.inflearn.com/course/web-game-react
(2022년 react 18 버전 기준 / but 아직 실무에서는 17이 더 흔히 보일 것)
- create react app : 실무에서도 사용하지만 강의에서는 원시적인 형태부터 진행 할 예정
- 리액트 감 잡기 : 아무 페이지에서 state 찾기 (바뀌는 것)
- react가 화면을 만들어주고 우리는 데이터에만 신경 쓰면 됨, document.querySelector 이런건 사용 X (돔에 직접 접근하고싶을때는 ref 사용)
- setState할때는 render 함수 실행 됨
- render에 함수 적어주면 새로 계속 함수가 생성해줌
- react는 데이터가 바뀌면 화면이 바뀜, 화면에 바뀔 부분들을 state로 만들어 둠
- 객체를 함부로 바꾸지 마라(불변성), 객체를 복사해서 데이터 바꿔 사용 / pop, push 등 사용 X concat 등 사용 (함수, 배열 등 도 객체)
- 컴포넌트가 리렌더링되는 경우
- state 바뀔 때
- props 바뀔 때
- 부모컴포넌트가 리렌더링되면 자식컴포넌트도 리렌더링됨
- but 값이 안바껴도 useState 함수 호출만하면 렌더링이 일어남
컴포넌트 제작
ReactDOM.render(<LikeButton/>, document.querySelector('#root'));
ReactDOM.createRoot(document.querySelector('#root')).render(<LikeButton/>);
- 컴포넌트란 데이터와 화면을 하나로 묶으둔 것
- 컴포넌트 제작 방식 : class 방식(요즘 안씀 ErrorBoundary 에서 1% 정도 사용) vs 함수 방식
JSX
- html 보다 더 엄격
- js코드는 {}로 감싸줘야함
- 닫는태그 꼭 필요 (ex.
<input/>
)
- for, if 문 사용 불가로,대신 삼항 연산자, 배열의 map 많이 씀
- return 에서는 상위 태그가 하나여야 함 (fraament
<></>
사용 가능)
- class 대신 className 사용, for대신 htmlFor 사용
- 주석 :
{/**/}
- 가독성있게 코딩하는게 약간 어려움
- JSX에서 null은 태그가 아예없음 의미
컴포넌트 제작 방식 - class
- 구 state로 신 state 만들때는 함수형 setState 사용해야 문제가 안생김
- React.createRef() 사용하면 리액트훅의 ref와 유사하게 사용 가능 (.current. 로 접근 가능)
컴포넌트 제작 방식 - React Hooks
- 함수 컴포넌트(함수형컴포넌트 아님, this 쓸 일이 없음)에 state, ref 기능을 추가한 것
- class 컴포넌트 대신으로 사용, React는 Hooks 권장
- setState 대신 useState 사용
- 함수컴포넌트 특성상 코드 전체가 렌더링될 때 마다 계속 실행됨 (useState에 함수 넣을 때 주의 : lazy init)
- state를 바꾸면 함수 전체가 다시 실행하기 때문에 조금 더 느릴 수 있음
- memo() 는 부모 컴포넌트가 리렌더링될 때 자식 컴포넌트가 리렌더링되는 것 막아줌
- ref 사용법이 클래스 컴포넌트와 다름
function LikeButton() {
const [liked, setLiked] = React.useState(false);
if(liked) {
return 'You liked this.';
}
return (
<button onClick={()=>{setLiked(true);}}>Like</button>
)
}
state
- render 안에서 state바꿔주면 무한 루프
컴포넌트분리 & props
- 반복문 단위로 분리하는 경우가 많음
- 부모컴포넌트 -> 자식컴포넌트 (this.props.*) props로 데이터 전달
- 컴포넌트 props가 있다면 '부모가 있겠구나' 생각하기
- 리액트의 대부분 문제는 prop에서 생 / 고조할아버지->나, 나->증조할아버지 막 이런식으로 props 관계가 복잡해서 이를 관리하기위해서 생긴게 redux, context, mbox 등
- props는 부모가 바꿔야 함 자식이 바꾸는건 금지
- props를 자식에서 바꿔야하는 경우 props를 자식컴포넌트의 state에 넣어주고 state를 바꿔줌 / 그래야 부모한테 영향이 안감
- contextAPI
- A 컴포넌트 > B 컴포넌트 > C 컴포넌트 > ... > G 컴포넌트
A -> G로 바로 props를 넘기고 싶으면? context 사용 (context를 좀 더 응용한건 redux)
- props를 받는다는건 렌더링이 될 수도 있다는 것임
ref
- 돔에 직접 접근할 때 사용
- hook에서는 this의 값을 접근할 때도 사용
- setState하면 return 재실행 (리렌더링) / useRef() 값을 바꾸면 return 재실행 X (리렌더링 X) 값은 바뀌지만 화면에는 영향을 미치지 않을 때 timeout, interval 은 보통 useRef로 쓰임(ref면 .current로 접근 해야 함)
... 5-1. 리액트 라이프사이클 소개 ING ...
- 바뀌지않는데 렌더링되는 부분이 있다면 성능 이슈 야기
- shouldComponentUpdate 사용해서 언제 렌더링할지 추가 처리
- PureComponent(클래스 컴포넌트에서만 사용)는 shouldComponentUpdate를 구현해둔 컴포넌트(state 바뀜 유/무 확인, 배열이나 객체와 같은 참조관계가 있는 경우 주의(참조관계가 바껴야 인지), state에서는 객체안쓰는게 좋음) 부모컴포넌트가 리렌더링되면 자식컴포넌트도 리렌더링됨 / 컴포넌트가 복잡해지면 PureComponent 못 쓰는 경우도 있음
- 리액트 훅에서는 memo() 사용하면 부모 컴포넌트가 리렌더링될때 자식 컴포넌트가 리렌더링되는 문제 막아줌 / displayName 으로 컴포넌트 이름 다시 바꿔줘야 함
기타
- 컨트롤드 인풋 vs 언컨트롤드 인풋 (컨트롤드 인풋 권장, 언컨트롤드 인풋 사용하는 케이스 정의되어 있음)
<input
ref={inputEl}
value={value}
onChange={{(e)=> setValue(e.currentTarget.value)}}
/>
<input defaultValue="value를 넣으면 컨트롤드 인풋으로 간주" ref={inputEl}/>
- require: 노드의 모듈 시스템 CommonJS, node에서는 require 만 지원
import: ES15 모듈 시스템, react 에서는 import 사용
- 리액트 렌더링 기준은 구 state, 현 state 가 다를 때 (참조가 달라야 함)
arr1.push(1)
const arr2 = [...arr1, 1]
- render 의 return 안(JSX)에서는 for, if를 못씀 / 대신 삼항연산자, && 연산자 등 사용
React 강의
https://www.inflearn.com/course/react-typescript-webgame
읽을거리
Top 10 React Component Libraries/Frameworks for 2022
https://velog.io/@warmwhiten/Top-10-React-Component-LibrariesFrameworks-for-2022-%EB%B2%88%EC%97%AD