Search

React 실습하기 1탄

Status
UPLOADING
Date
2024/03/08
Tags
React

1. 프로젝트 생성

프로젝트 폴더를 설치하고 싶은 경로로 이동해 다음 명령어를 실행해줍니다.
npx create-react-app [Project]
Java
복사
긴 텍스트가 출력되며 성공적으로 프로젝트가 만들어진다면 다음과 같은 문구를 확인할 수 있습니다.

2. VSCode에서 열기

VSCode를 설치하고 프로젝트를 열면 다음과 같은 패키지 구조를 확인할 수 있습니다.
좌측 상단의 터미널을 열고 npm start 를 쳐줍니다.
그러면 브라우저에 다음과 같은 화면이 뜹니다.
신기한건 src/App.js 에서 코드를 바꾼다면 즉시 반영됩니다.
패키지 디렉토리를 분석해보겠습니다.
node_modules 에는 프로젝트에서 사용하는 dependency 모델들이 모여있습니다. 해당 디렉토리에 사용되는 의존성은 모두 package.json에 기록되어 있습니다.
실수로 node_modules를 삭제했다면 npm install 명령어를 통해 그대로 다시 설치할 수 있습니다. 해당 디렉토리는 매우 크기 때문에 Git에 따로 업로드 하지 않지만 다른 개발자들은 package.json을 통해 dependency를 다운로드 받을 수 있습니다.
public/index.html 에는 <div id=”root”> 가 있습니다.
이 밑으로 리액트 코드가 실행되어 만들어진 DOM이 실행되게 됩니다.
대부분의 작업들은 src 디렉토리 밑에서 진행됩니다.
index.js를 보면 import App from ‘./App’; 을 볼 수 있는데요, 이는 App.js를 불러오는 코드입니다.
앞 부분에서 잠깐 보았을 때 App.js에서 문구를 살짝 바꾸면 바로 반영된걸 확인할 수 있었습니다.
하단의 코드는 id가 root인 부분에 앱을 랜더링 시켜준다고 이해하면 됩니다.
const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> );
Java
복사
다시 한번 언급하지만 우리는 App.js 밑에서 어플리케이션을 구현하면 됩니다. 바로 반영되는 것을 Hot Module Replacement (HMR) 라고 합니다.
이전에 npm start 명령어를 통해 앱을 실행했는데요, 명령어들은 package.json에 정의되어 있습니다.
개발자 도구로 페이지를 열어보면 rootApp을 볼 수 있습니다.
그리고 이는 App.jsclassNameApp가 동일합니다.

3. 컴포넌트

아래는 네이버 홈 페이지 중 일부입니다. 전체적인 부분을 다 작업한건 아니지만 빨간색 박스 모두가 하나의 컴포넌트라고 생각하면 됩니다.
하단의 뉴스 테이블을 보면 여러 언론사비슷한 템플릿으로 디자인 되어 있는걸 확인할 수 있는데, 하나를 컴포넌트를 만들어 놓는다면 컴포넌트를 재사용하면서 모든 언론사들에 대해 비슷한 동적으로 작업을 수행하도록 구현할 수 있습니다.
컴포넌트 = 재사용
아까 살펴보았던 App.js도 하나의 컴포넌트 이며, index.js에서 해당 컴포넌트를 사용하고 있습니다.
App.js는 함수로 구성되어 있어, 함수형 컴포넌트라고 불리며 모든 컴포넌트는 대문자로 시작해야 합니다. 그리고 App.js가 반환하는 것은 JSX 입니다.
App.js를 변경해볼까요?
변경한 코드와 페이지 입니다.
function App() { const name = "Tom"; const user = { name : "Jane" } return ( <div className="App"> <h1 style = {{ color : "#f0f", backgroundColor : "green" } } > <p>Hello, {name}</p> <p>Hi, {user.name}</p> </h1> </div> ); } export default App;
Java
복사
우선 변수를 선언하거나, json 형식으로 데이터를 정의할 수 있고 이를 컴포넌트 내에서 사용할 수 있습니다. 그리고 태그 안에는 자바 스크립트 형식의 스타일 코드를 정의할 수 있습니다. 참고로 css 와는 다른 변수 스타일로 정의해야 합니다.
App.js는 하나의 컴포넌트로 만약 index.js에 여러 <App /> 을 사용한다면 하단의 페이지는 계속해서 나타날 것입니다.

3-1. 컴포넌트 만들기

컴포넌트는 component 패키지를 만들어 별도로 관리해주도록 합시다.
컴포넌트를 정의하는 방법은 다양합니다.
// 1 const Hello = function () { return <p>Hello</p>; } // 2 const Hello = () => { return <p>Hello</p>; } export default Hello;
Java
복사
혹은 바로 export 해주는 방법도 존재합니다.
export default function Hello() { return <p>Hello</p>; }
Java
복사
App.js에서 컴포넌트를 주입하고 싶다면 다음과 같이 코드를 작성하면 됩니다.
import logo from './logo.svg'; import './App.css'; import Hello from './component/Hello' function App() { const name = "Tom"; const user = { name : "Jane" } return ( <div className="App"> <Hello/> </div> ); } export default App;
Java
복사
Hello 컴포넌트 내에 World 컴포넌트를 포함해도 됩니다.
import World from './World'; export default function Hello() { return ( <div> <h1> Hello </h1> <World/> </div> ); }
Java
복사
페이지 구성은 다음과 같아집니다.

4. CSS 작성법

create react app으로 프로젝트를 만들었다면 별도의 설치 없이 사용할 수 있는 CSS 작성법세 가지가 존재합니다.
인라인 스타일
별도의 새로운 파일 없이 객체로 태그 안에 작성하는 스타일입니다. 이전에도 한번 다뤄보았던 내용입니다.
주의 할 점은
객체 스타일로 작성
camelCase로 작성
CSS 파일
두 번째 방법은 프로젝트 생성 시 포함되었던 index.css에 스타일을 작성하는 것입니다.
다만 주의할 점은 css 속성 간 충돌입니다. 예를 들어, App.css와 Hello.css 두 파일에 같은 이름의 다른 속성을 정의했다고 가정해봅시다. 이렇게 작성한다면 충돌이 불가피합니다.
import World from './World'; import "./Hello.css"; export default function Hello() { return ( <div> <h1 style={{ color: "#f00", borderRight: "12px solid #000", marginBottom: "50px", opacity: 1, }}> Hello </h1> <div className="box"/> </div> ); } // Hello.css .box { width: 200px; height: 50px; background-color: blue; } // App.css .box { width: 100px; height: 100px; background-color: red; }
Java
복사
CSS 모듈 파일
Hello.module.css 파일을 생성합니다. 그리고 Hello.js에는 다음과 같이 적용합니다.
import World from './World'; import styles from "./Hello.module.css"; export default function Hello() { return ( <div> <h1 style={{ color: "#f00", borderRight: "12px solid #000", marginBottom: "50px", opacity: 1, }}> Hello </h1> <div className={styles.box}> Hello </div> </div> ); }
Java
복사
App.js에도 특화된 App.module.css 파일으 생성하고 다음과 같이 작성합니다.
import './App.css'; import Hello from './component/Hello' import styles from './App.module.css' function App() { return ( <div className="App"> <Hello/> <div className={styles.box}>App</div> </div> ); } export default App;
Java
복사

5. 이벤트 처리

이벤트를 만드는 첫 번째 방법은 미리 함수를 정의해 놓는것입니다.
import World from './World'; import styles from "./Hello.module.css"; export default function Hello() { function showName() { console.log("Mike") } function showAge(age) { console.log(age); } return ( <div> <h1> Hello </h1> <button onClick={showName}>Show name</button> <button onClick={ () => { showAge(30); } }>Show age</button> </div> ); }
Java
복사
위 코드에 따르면 버튼을 누를 시 console에 “Mike”가 연달아 찍히는 것을 확인할 수 있습니다.
이벤트는 onClick 대신 onChange 함수를 사용할 수도 있습니다. 이 때는 변경이 감지될 때 마다 console에 기록됩니다.

6. state, useState

state컴포넌트가 가지고 있는 속성 값입니다. state 값이 변하면 react는 자동으로 UI를 변경시켜줍니다.
import {useState} from "react"; export default function Hello() { const [name, setName] = useState("Mike"); function changeName() { name = name === "Mike" ? "Jane" : "Mike"; } return ( <div> <h1> Hello </h1> <h2> {name} </h2> <button onClick={() => { setName(name === "Mike" ? "Jane" : "Mike"); }}>Change</button> </div> ); }
Java
복사
useState()는 배열을 반환합니다.
배열의 첫 번째 값은 state (변수명) 이고, 두 번째는 state를 변경해주는 함수입니다.
+ 추가적으로 useState()를 사용할 때는 react에서 꼭 useStateimport 해주어야 합니다.
우측의 예제를 보시면 Hello 컴포넌트 여러 개를 동시에 사용하더라도 그 안에 있는 state 값은 공유되지 않습니다. 즉, 각각의 state가 별도로 관리되고 있습니다.

7. properties

컴포넌트가 관리하는 상태 값이 state 라면 props는 속성 값을 의미합니다.
function App() { return ( <div className="App"> <h3>props : properties</h3> <Hello age={10}/> <Hello age={20}/> <Hello age={30}/> </div> ); } ... import {useState} from "react"; export default function Hello(props) { const [name, setName] = useState("Mike"); const [age, setAge] = useState(props.age); return ( <div> <h2 id = "name"> {name}({age}) </h2> <button onClick={() => { setName(name === "Mike" ? "Jane" : "Mike"); setAge(age + 1) }}>Change</button> </div> ); }
Java
복사
props에서 주의할 점은 매개 변수로 넘겨 받은 값을 강제로 바꿀 수 없습니다.