221019.til

Universe·2022년 10월 19일
0

study

목록 보기
37/49
post-custom-banner

React 를 사용하는 이유 ?

Single Page Application 을 좀 더 쉽게 만들고 싶어서.
새로고침 없이 부드럽게 동작하는 웹 페이지를 좀 더 쉽게 만들고 싶어서.
가장 오래되고 가장 유저가 많아서.
HTML 의 재사용이 굉장이 편리하다.
컴포넌트 단위로 관리하기 때문.
React Native 로 앱 개발도 쉽게 할 수 있다.

개발환경 세팅

Create React App 을 이용

  1. Node.js 설치
  2. 폴더를 하나 생성하고 터미널로 열어서
npx create-react-app 프로젝트명
  1. 에디터로 폴더를 열기
  2. 미리보기는 터미널에서 npm start

node_modules : 라이브러리 코드 보관함
npm 을 이용해서 무언가 설치하면 저 폴더에 들어간다
public : html, img 파일을 보관함
src : 소스코드 보관함. App.js 이 메인
package.json : 라이브러리를 설치하면 버전이나 설치정보 등이 들어간다

JSX

react 에서는 자바스크립트 내에 html 을 작성하는데,
jsx 는 js파일에서 html 을 좀 더 쉽게 작성할 수 있게 도와준다.

css 를 적용하고 싶다면 import 해온다.

import "./App.css";
export default App;

import 한 css파일을 export defalut 해주면 적용된다.

JSX는 HTML 이 아니므로 class 키워드를 쓸 수 없다.

자바스크립트로 html 태그를 추가하려면

document.querySelector('추가할대상').insertAdjacentHTML...
// 혹은
document.querySelector('추가할대상').createElement(...)

이런식으로 추가를 해야한다.
그런데 이러한 방식은 직관성도 떨어질 뿐더러 개발 난이도도 너무 어려워지므로 JSX 는 이러한 문제를 해결하여

function App() {
  return (
    <div className="App">
      <div className="nav">
      </div>
    </div>
  );
}

이런식으로 기존 HTML 파일을 개발하듯 코딩을 할 수 있다.
그런데 HTML 에서 선택자로 쓰이는 class 문법은 자바스크립트의 class 문법과 다르다.
예약어로 설정되어 있기 때문에 JSX에서는 class 문법을 className 으로 대체하여 사용한다.

변수를 선언하는 방법

function App() {
  let post = '블로그';
  return (
    <div className="App">
      <div className="nav">
        <h4>{post}</h4>
      </div>
    </div>
  );
}

return 상단에 변수를 선언하고 중괄호를 이용하여 변수를 사용할 수 있다.
변수를 HTML 에 넣어 사용하는 작업을 데이터바인딩 이라고 한다.

style 속성도 사용할 수 있다

function App() {
  let post = '블로그';
  return (
    <div className="App">
      <div className="nav">
        <h4 style={{color:'red', fontSize:'30px'}}>{post}</h4>
      </div>
    </div>
  );
}

h4 부분을 보자.
기존 HTML 을 작성하던 방식과는 조금 다른데,
style 속성을 오브젝트 처럼 기입해야 적용할 수 있다.
sytle = {} 안에 오브젝트로 집어넣는다.

주의사항

작성할 HTML 코드는 반드시 return() 내부에 작성해야 한다.
또한 병렬로 태그를 작성할 수 없다.
예를들어,

function App() {
  return (
    <div className="App">
    </div>
		<div></div>
  );
}

이런식으로 작성할 수 없다.

State

react 식 변수를 저장하는 방법.

import {useState} from 'react';

function App(){
	let [데이터내용,스테이트변경시실행할함수] = useState('데이터')
}

useState 는 배열로 저장이 되어 let [a,b] 식으로 정의하면 (구조분해할당 작업이다)
a에는 state 에 저장된 데이터, b는 state 가 변경되었을 때 실행할 함수를 가리킨다.

state 를 쓰는 이유가 무엇일까 ?
가장 큰 차이점이라면 state 는 변동사항이 생기면 state 를 사용하는 html 로 자동 재렌더링 해준다는 점에 있다.
기존의 변수는 변경되었을 때,
‘이 변수가 변경되면 html 을 변경해주세요’ 라고 따로 작업을 명령해주어야 하는데,
state 로 선언된 변수는 자동으로 재렌더링하여 변경한다.
새로고침을 하지 않아도 HTML 이 자동으로 변경되므로
single page app 개발에 좀 더 용이하다.

반대로 생각해서, 굳이 변경할 일이 없는
웹 사이트의 로고나 네이게이션 바의 항목 같은 경우에는 굳이 state 로 저장할 필요가 없다.
요점은 ‘변경이나 상태의 변화를 주시해야 하는 요소’를 state 로 저장하면 좋다는 것이다.

State 활용법

state 는 두개의 항목으로 정의된다.

function App(){
	let [a,b] = useState('데이터들')
}

a가 데이터라면 b는 데이터가 변경되었을 때 재렌더링 해줄 함수를 명시한다고 했다.
자바스크립트의 이벤트를 이용해
특정 조건을 만족시키면 state를 변경해주십시오 라고 코딩을 한다면 어떨까 ?
우선 이벤트를 만들어보자.

function App(){
	function func(){
		console.log(1)
	}
	return (
		<button onClick={func}> 버튼을 누르면콘솔에 1 출력 </button>
	)
}

onClick 키워드를 사용하여 클릭이벤트를 감지해줄 수 있다.
onClick 내부에는 함수의 이름이 들어간다. 함수의 이름.
함수() 같은 식으로 함수의 실행하는 실수에 주의.

<button onClick={()=>{}}> 내용 <button>

함수명을 쓰지 않고 직접 함수를 정의하거나 arrow function 을 사용할 수도 있다.
직접 기능 개발을 해보자.
[1,2,3,4,5] 라는 배열이 state 로 저장되어 있고 이 배열을 출력해주는 span 을 만들었다.
특정 버튼을 클릭하면 버튼에 1씩 더해서 재렌더링 해주는 기능을 구현해보자.

function App() {
  let [num, numChange] = useState([1, 2, 3, 4, 5]);
  return (
    <div className="App">
      <button
        onClick={() => {
          let copy = [...num];
          let change = [];
          copy.forEach((e) => {
            e++;
            change.push(e);
          });
          numChange(change);
        }}
      >
        change number
      </button>
      <span>{num}</span>
    </div>
  );
}

리엑트를 처음 써봐서 잘 된 코딩인지는 잘 모르겠다..
지금은 state 사용법을 익히는 중이니 수정할 수 있다면 나중에 한번 수정해보자.

순서대로 살펴보자면
우선 첫번째.
state 를 span 태그에 꺼내주기 위해 {} 중괄호로 num을 불러주었다.
두번째,
button에 onClick 이벤트를 추가하여 버튼을 클릭하면 감지하여 함수를 실행해 줄 수 있도록
onClick 내부에 함수를 구현했다.
세번째,
state 로 선언된 배열을 copy 라는 변수에 재할당했다.
재할당 하는 과정에서 spread operator 를 사용했다.
배열에 spread operator 를 사용한 후 다시 묶어주면 똑같은 새로운 배열을 만들 수 있다.

왜 이렇게 해야할까 ?
우선 개발을 할 때, 원본 데이터 수정을 지양해야 한다는 점과 깊은복사 & 얕은복사의 개념이다.
reference data type인 배열이나 오브젝트를 변수로 선언할 때,
해당 데이터를 복사해오는 것이 아니라 데이터가 저장된 장소의 주소를 저장한다.
따라서 이 경우에 예를들어 이런식으로,

<button
        onClick={() => {
          let copy = num;
          let change = [];
          copy.forEach((e) => {
            e++;
            change.push(e);
          });
          numChange(change);
        }}
      >
        change number
      </button>

state 배열을 그대로 copy 변수로 복사하려고 하면
변경점을 체크하여 재렌더링하는 state 의 변경함수가 작동하지 않는다.
왜냐하면 저런식의 복사는 주소만 복사하기 때문에
내부의 데이터 변경 여부와는 상관없이 두 변수가 가리키는 주소 는 똑같기 때문이다.

깊은 & 얕은 복사 개념은 반드시 제대로 이해하고 넘어가야 할 것 같다.

완성된 구현내용

Component

위에서 공부했던 것 처럼, 병렬로는 HTML 덩어리를 작성할 수 없다.
return() 안에 두개의 div box 를 만들 수 없다는 이야기.
반드시 두개의 div box 를 넣어야만 한다면

function App(){
	return(
		<div>
			<div>기능개발</div>
			<div>기능개발</div>
		</div>
	)
}

하나의 div로 묶는다거나,

function App(){
	return(
		<>
			<div>기능개발</div>
			<div>기능개발</div>
		</>
	)
}

의미없는 괄호를 사용하여 묶을 수 있다.
이 방법을 fragment 문법이라고 한다. 직역하자면 파편 혹은 부서진 조각 이라는 의미.

그렇다면 HTML 이 아주 많아지면 어떻게 해야할까 ?
그것들을 다 div로 묶는 것 보다 조금 더 편리한 방법이 react 의 component 문법.
예를들어,

function App() {
	return(
		<div>
			<Comp2/>
		</div>
	)
}

function Comp2(){
	return (
		<div>기능개발</div>
	)
}

사실 상단의 App 도 하나의 component 이다.
이렇게 축약한 HTML 덩어리를 component 라고 부른다.
react 개발의 핵심은 이런식으로 component 단위로 개발하는데 있다.

App() 의 return 내부에서 정의한 component를

<Comp2></Com2>
혹은
<Comp2/>

이런식으로 호출하면 해당 component 를 호출한 자리에 넣어 렌더링한다.
보통 component 의 첫 스펠링은 대문자로 기입하는게 관습이다.

component 는 정말 편리한 문법이고 이 기능이 react 의 핵심이지만 남발해서는 안된다.
왜냐하면 component 가 많으면 많을수록 유지보수가 힘들어지고,
변수의 선언 및 관리도 복잡해지기 때문이다.
따라서 component 는

  1. 반복해서 출현하는 덩어리 HTML
  2. 변경이 자주되는 덩어리 HTML
  3. 각각의 웹 페이지를 컴포넌트 단위로 관리

이러한 경우에 만드는게 바람직하다.

component 를 활용한 react 기능개발

동적인 UI 를 만들어보자.
기존의 자바스크립트로 UI를 개발할 때는,

1.html / css 로 초기상태, 최종상태 디자인을 한다.
2.특정 이벤트를 만족하면
3.초기상태에서 최종상태로 변경시킨다.

그런데 react 의 UI 개발은 다음과 같은 단계를 따른다.

  1. html / css 로 디자인을 한다.
  2. UI의 현재 상태를 state 로 저장한다.
  3. state 의 상태에 따라서 UI가 어떤 식으로 바뀔 지 조건문 등으로 판별한다.

기존의 자바스크립트와 조금 다른데,
자바스크립트는 UI를 만들 때 HTML 을 직접 조작해야한다.

style.background = ‘black’

이런식으로 말이다.

그런데 react 는 스위치의 온 오프 처럼
스위치가 ‘ON’ 이면 불이 켜지고, 스위치가 ‘OFF’ 이면 불이 꺼지는 식으로 개발을 한다.
예를들어, 버튼을 누르면 모달창을 띄워주는 UI를 개발한다고 하면

let [modal, setModal] = useState(false);

초기상태를 false 로 설정하고
버튼을 눌렀을 때 true 로 상태를 변경하는 식으로 코딩을 하면 되겠다.

주의할 점.
JSX 내부의 자바스크립트 표현식에서는 if, for 같은 자바스크립트 문법을 사용할 수 없다.
그렇다면 조건이 필요한 내용을 작성해야할 때는 어떻게 해야할까 ?

두 가지 방법이 있는데

  1. JSX 밖, 그러니까 return() 외부에서 if 문을 이용해 값을 설정한 후 집어넣는다.
  2. return() 내부에서 삼항연산자를 사용한다.

삼항연산자는,

(조건 ? 참일경우 : 거짓일경우)

식의 조건문이다.

그럼 이제 모달창을 만들어보자.
위에서 state 는 정의 했으므로,
App() 의 return() 내부에

function App(){
	return(
		...
		{modal == true ? <Modal></Modal> : null}
	)

이런식으로 modal 의 값이 true 일 때 Modal component 를 띄워주고,
false 일 때 null, 존재하지 않게 만들면 되겠다.
return 내부는 JSX 의 영역이므로 삼항연산자를 사용했다.

<div className="list" onClick={showModal}></div>

이벤트를 감지할 대상에 onClick 이벤트로 함수를 선언하고 (콜백함수로 만들어도 무관)

function showModal() {
    if (modal === false) {
      setModal(true);
    } else {
      setModal(false);
    }
  }

만약 클릭했을 때 modal 의 값이 false 라면 state 를 true 로 변경해주고
true 일 경우에 false 로 바꿔주는 스위치 기능을 구현했다.
정의된 함수는 return 외부에 있으므로 if문을 사용해 구현한 모습.

구현한 내용

profile
Always, we are friend 🧡
post-custom-banner

0개의 댓글