리액트 공식 문서의 시작하기 참조
1. 온라인 플레이그라운드에서 바로 코딩 시작
2. 컴퓨터에 리액트 개발 환경을 세팅: Create React App / React 프로젝트 가이드
15버전 이상 17버전 미만 최신버전 설치
Visual Studio Code 등의 에디터 설치
원하는 위치에 프로젝트 폴더 생성("react"라는 이름은 피할 것)
에디터에서 프로젝트 폴더 열기
프로젝트 폴더에서 npx create-react-app .
npm start
리액트 개발환경 실행
위 샘플 애플리케이션 화면이 뜨면 코딩 준비 완료
프로젝트 폴더/src/index.js
앱의 입구 파일. 여러가지 전역적인 설정이 들어감. index.js
가 import하는 App.js
에 애플리케이션의 실질적인 코드가 들어 있음
프로젝트 폴더/src/App.js
애플리케이션의 실질적인 코드가 들어 있음. App.css
를 import함
프로젝트 폴더/src/App.css
App.js
의 디자인 코드
터미널에서 ctrl+c
로 개발환경을 끈 후
npm run build
로 build 폴더(배포판) 만들기
npx serve -s build
사용자가 어떤 경로로 들어오든 build 폴더의 index.html
을 서비스하는 서버 열기
Javascript Extension
js의 확장 문법으로, 리액트에서 컴포넌트를 만드는 데 활용
js내에 html을 한 언어처럼 쓸 수 있게 하는 기능
아래 컴포넌트 만들기
의 문법 규칙 = JSX 문법
// 파일1.js
function 앱이름() {
...
...
}
...
export default 앱이름
// 파일2.js
import 앱이름 from "파일1의경로/앱이름"
한 파일당 하나의 함수만 export default로 내보낼 수 있음
컴포넌트 = 사용자 정의 태그
함수를 정의하여 컴포넌트 생성
function 컴포넌트명(){
return html코드
}
// 컴포넌트명은 반드시 대문자로 시작
생성 후 컴포넌트를 넣을 자리에 삽입
...
<컴포넌트명></컴포넌트명>
...
컴포넌트에서 return하는 html 코드는 반드시 닫는 부분이 있어야 함
<a>
나 <image>
처럼 닫는 부분이 없는 경우 <a/>
<image/>
로 써 주면 됨
컴포넌트에서 return하는 html 코드는 반드시 하나의 부모 태그 안에 있어야 함
부모 태그를 쓰고 싶지 않은 경우 <React.Fragment></React.Fragment>
라는 임의의 부모 태그로 묶을 수 있으며, 이는 <>...</>
로 생략하여 사용 가능
html 태그의 class는 JSX 문법에서 사용 불가
대신 <div className='클래스명'></div>
형태로 사용 가능
별도의 css 파일을 만들거나, js파일에 스타일을 객체로 선언해서 사용 가능(인라인 방식)
이때 css 속성명은 camelCase로 써야 함
const style = {
키1: {
backgroundColor: 'black',
},
키2: {
color: 'red',
}
};
return (
<div style={style.키1}>
</div>
)
html 안에 {변수}로 변수나 표현식 삽입 가능
숫자, 문자열, 표현식은 삽입 가능하지만 다른 자료형(객체, 배열 등)은 삽입 불가
props = 컴포넌트에 데이터를 전달하는 가장 효율적인 방식
컴포넌트에 속성(prop, 함수의 인자와 유사)을 입력하여 속성에 따라 컴포넌트가 다르게 구현되도록 만들 수 있음
function 컴포넌트명(props){
return html코드*
}
...
<컴포넌트명 prop명=값></컴포넌트명>
...
*html코드 안에 {props.prop명}을 삽입하여 설정한 prop값을 나타낼 수 있음
자동으로 생성한 태그의 경우에는 key
라는 약속된 prop을 부여해야 함
prop으로 문자열, 숫자 등의 정적 데이터 뿐만 아니라 동적인 데이터(state)나 컴포넌트도 넘겨받을 수 있음
컴포넌트명.defaultProps = ...
기능을 통해, prop의 초기값을 부여받지 않더라도 오류가 나지 않게 처리할 수도 있음
컴포넌트에 이벤트 부여하기
function 컴포넌트명(props){
return html코드...함수명={function(event){
event.preventDefault(); // 함수가 실행될 때마다 전체 코드가 리로드되는 것을 방지
props.내가만든함수명();
}}...
}
...
<컴포넌트명 내가만든함수명={function(){내가만든함수가 호출되면 실행할 코드;}}></컴포넌트명>
...
컴포넌트에서 함수명이라는 함수가 실행(ex. onClick
) --> 컴포넌트의 props 중 내가만든함수명이라는 함수 호출(by props.내가만든함수명();
) --> 내가만든함수가 호출되면 실행할 코드 실행
함수의 인자가 1개인 경우에는 (event)
를 event
로 써도 무방
arrow function(=>
)을 사용하여 위 코드를 다음처럼 표현할 수도 있음
function 컴포넌트명(props){
return html코드...함수명={(event)=>{
event.preventDefault(); // 함수가 실행될 때마다 전체 코드가 리로드되는 것을 방지
props.내가만든함수명();
}}...
}
...
<컴포넌트명 내가만든함수명={()=>{내가만든함수가 호출되면 실행할 코드;}}></컴포넌트명>
...
state = 계속해서 변화하는 특정 상태, 상태에 따라 각각 다른 동작을 하게 됨
컴포넌트의 state가 변할 때마다 해당 컴포넌트의 함수가 호출되어 rerender됨
컴포넌트 함수가 prop을 받아서 return하면 return값이 곧 새로운 UI가 됨
컴포넌트 함수를 재실행해서 새로운 return값을 만들어주는 데이터: prop, state
컴포넌트 함수는 prop과 state를 받아서 새로운 return값을 만들어서 UI를 변화시킴
하지만 prop은 컴포넌트를 사용하는 외부자를 위한 데이터인 반면, state는 컴포넌트를 만드는 내부자를 위한 데이터라는 차이가 있음
function 컴포넌트명(props){
return html코드...함수명={(event)=>{
event.preventDefault(); // 함수가 실행될 때마다 전체 코드가 리로드되는 것을 방지
props.내가만든함수명();
}}...
}
...
const [상태명, 상태를변경하는함수명] = useState(상태의 초기값);
...
<컴포넌트명 내가만든함수명={()=>{내가만든함수가 호출되면 실행할 코드;}}></컴포넌트명>
...
useState()는 배열을 리턴: 리턴하는 배열의 0번째 원소(상태명[0]
)는 상태의 값을 읽을 때 쓰는 데이터이고, 1번째 데이터(상태명[1]
)는 그 상태의 값을 변경할 때 사용하는 함수
useState(인자)의 인자는 상태의 초기값. 초기값이 없을 경우 useState(null)로 씀
상태를변경하는함수명: 상태의 값을 변경하는 함수의 이름
예시)
리액트 애플리케이션의 CRUD
오리지널 객체를 변경하여 사용 vs 오리지널 객체의 복사본을 변경하여 사용
오리지널 객체의 내용이 변했을 때에만 컴포넌트 리렌더링(같은 데이터라면 렌더링하지 않음)
CRUD
이전 파트 내용에 함축되어 있음
create + read 를 복합적으로 사용하여 구현