정보실

웹학교

정보실

Reactjs React를 시작하는 방법 — 초보자를 위한 현대적인 프로젝트 기반 안내서 (후크 포함)

본문

React를 배우고 싶습니까? 그럼 당신은 바로 이곳에 왔습니다. 이 안내서는 React를 시작할 때 알아야 할 모든 것을 안내합니다.


기본 개념의 "방법과 이유"를 설명하고 API에서 데이터를 가져 오는 작은 프로젝트를 구축하여 모든 것을 실제로 볼 수 있습니다.


이것은 긴 것이므로 아래의 "섹션으로 이동"링크를 사용해야 하는 경우 섹션을 건너 뛰거나 다시 읽습니다. 그 방법으로 음료를 마시고 버클을 꽂고 시작합시다.


https://www.freecodecamp.org/news/getting-started-with-react-a-modern-project-based-guide-for-beginners-including-hooks-2/ 


전제 조건 


이 안내서를 읽기 전에 React를 알 필요는 없습니다. 그러나 이 React 안내서를 최대한 활용하려면 숙지해야 할 몇 가지 사항이 있습니다.


기본 JavaScript 


React는 JavaScript 라이브러리이므로 React를 배우기 전에 JavaScript를 아는 것이 좋습니다. 걱정하지 마십시오. JavaScript를 알 필요가 없습니다. 기본 사항만 알면 됩니다.


  • 변수, 함수, 데이터 타입
  • 배열과 객체
  • ES6 구문 (let & const, Arrow Functions, Destructuring Assignment, 클래스, 가져 오기 / 내보내기 등 사용)
  • JavaScript를 사용하여 DOM을 조작하는 방법


기본 HTML 


React에서는 JSX라는 것을 사용하여 웹 페이지용 HTML을 만듭니다. JSX에 대해서는 나중에 자세히 설명하지만 지금은 HTML과 관련하여 좋은 기초가 있는지 확인하십시오.


  • HTML을 구성하는 방법 (요소를 중첩 하는 방법 등)
  • HTML 속성 (예 : "id", "class", "onclick"등)


개발 환경 


가장 먼저 할 일은 개발 환경을 설정하는 것입니다. Node.js를 이미 설정하고 Visual Studio Code (또는 선호하는 IDE)를 설치 한 경우 다음 섹션으로 건너 뛸 수 있습니다.


Node.js 


여기에 가서 OS에 적합한 패키지를 다운로드하십시오 (Mac / windows 등)


설치가 완료되면 터미널을 열고 다음 명령을 입력하십시오.


node -v

방금 설치 한 노드의 버전이 출력으로 표시됩니다.

node.png 



이것은 node 명령이 작동하고 node가 성공적으로 설치되었음을 의미합니다. hurray! 오류가 표시되면 다운로드 한 패키지에서 Node를 다시 설치하고 명령을 다시 시도하십시오.


Visual Studio Code 


Visual Studio Code는 널리 사용되는 오픈 소스 IDE로 프론트 엔드 개발에 적합합니다. 당신이 시도 할 수 있는 많은 것들이 있습니다 – 당신이 가장 좋아하는 것을 보고, 원한다면 다운로드하십시오. 지금은 VS Code로 실행하겠습니다.


여기를 클릭하여 플랫폼에 맞는 버전을 다운로드하십시오.


설치 단계를 따르십시오. 계속해서 Visual Studio Code를 시작하십시오.


지금은 충분한 개발 설정입니다. 설치할 수 있는 다른 멋진 기능 (VS 코드 확장명 등)이 있지만 지금은 필요하지 않습니다. React를 배우기 위해 여기 있습니다!


리액트 앱 만들기 


다음 단계는 React 프로젝트를 만드는 것입니다. 운 좋게도 Facebook의 훌륭한 직원은 이것을 매우 간단하게 만들었습니다. 터미널 내에서 명령을 실행하기 만하면 됩니다.


npx create-react-app my-app

이것은 "my-app"라는 프로젝트를 만들고 모든 것을 자동으로 설정합니다. 정말 멋진.


계속해서 앱을 만들려는 디렉토리에서 터미널을 엽니다 (예 : "프로젝트"폴더를 열고 명령을 실행하십시오. 터미널이 그 일을 하도록 하고 잠시 후, 다음과 같은 명령이 완료되고 표시됩니다 :


cra-install.png 


create-react-app 출력에 앱을 시작하기 위해 수행해야 할 작업이 설명되어 있습니다. 계속해서 터미널에서 명령을 실행하십시오 :


cd my-app
yarn start

그러면 개발 서버가 시작되고 웹 브라우저가 열립니다.


cra-start.png 


첫 React 앱을 설정했습니다! 무슨 일이 일어나고 있는지 더 배우고 싶다면 ( "create-react-app" GitHub를 확인하십시오 :) [https://github.com/facebook/create-react-app]


React 앱 만들기 탐색 


Visual Studio 코드 (또는 설치 한 IDE)를 열고 파일> 열기…를 선택하고 create-react-app를 사용하여 방금 만든 my-app 폴더를 선택하십시오. IDE에 반짝이는 새로운 React 앱이 열리므로 코드를 작성할 수 있습니다!


오른쪽에 프로젝트 구조가 표시되어야 합니다.

project-tree.png 


그 모든 것을 보십시오! 많은 것을 걱정하지 마십시오. 대부분이 상용구 코드와 구성이므로 이 자습서에서는 다루지 않을 것입니다. 휴! 그러나 호기심 많은 개발자이므로 프로젝트 트리를 살펴보고 우리가 가진 것을 살펴 보겠습니다.


Node Modules 


NPM (Node Package Manager)을 통해 패키지를 설치하는 곳입니다. NPM에 익숙하지 않은 경우 다른 개발자가 직접 작성하는 대신 사용할 수 있는 코드 (일반적으로 오픈 소스)를 공유 할 수 있는 영광스러운 곳입니다.


기존 HTML에서와 같이 스크립트 태그를 사용하는 대신 이러한 모듈을 응용 프로그램의 일부로 설치합니다. 그런 다음 import 문을 사용하여 해당 모듈의 코드에 액세스합니다. 우리는 나중에 이것을 실제로 보게 될 것입니다.


Public 폴더 


여기에 번들 코드가 있습니다. 앱을 배포 할 준비가 되면 ** build script **를 실행하고 최종 파일은 여기에 있습니다. 이것은 일반적으로 HTML, JavaScript 및 CSS 파일입니다. 이 폴더는 웹 서버에 덤프하여 사용자가 URL을 통해 앱을 볼 수 있도록 합니다.


Index.html 


index.html은 진입 점이거나 사용자가 앱을 호스팅 하는 URL로 이동할 때 웹 브라우저가 가장 먼저 로드하는 것입니다.


파일을 살펴보면, 친숙 할 것으로 기대되는 일반적인 HTML로 구성된 일반적인 HTML 파일 일 뿐입니다. body을 보면 비어 있습니다. React는 React 코드를 HTML로 동적으로 변환하여 "root"div에 로드 합니다.


그 과정에서 코드의 수분이 많은 부분을 살펴 보겠습니다.


첫 번째 구성 요소 


프로젝트 트리에서 App.js를 엽니다. 이것은 우리 응용 프로그램의 주요 구성 요소입니다. 렌더링 되는 첫 번째 구성 요소입니다. 구성 요소의 "큰 치즈"입니다. 


우리가 큰 치즈 구성 요소에서 가장 먼저 할 일은 모든 것을 삭제하고 처음부터 자체 구성 요소를 작성하여 진행 상황을 더 잘 이해하는 것입니다.


이제 빈 슬레이트를 가지고 놀았으니 반응 가져 오기부터 시작하겠습니다. 이것은 React 라이브러리를 범위 내로 가져 와서 모든 멋진 기능에 액세스 할 수 있게 합니다.


import React from "react";

다음으로 함수를 선언합니다. 여기서는 ES6 화살표 함수을 사용합니다. 그것은 "구성 요소"가 무엇인지, 즉 논리와 마크 업이 있는 함수입니다. 또한 이 함수을 내 보내서 다른 곳에서 사용할 수 있도록 합니다.


const App = () => {

}

export default App;

함수 내에서 return()을 작성하려고 합니다. 이것이 이 컴포넌트에서 반환되는 것이며 HTML로 변환 및 렌더링 되는 마크 업을 포함합니다.


마지막으로 <h1> 제목 태그가 있는 <div>를 추가하겠습니다. 완성 된 구성 요소는 다음과 같습니다.


import React from "react";

const App = () => {
  return (
    <div>
       <h1>Hello React World</h1>
       <h2>
             This is our first React App - isn't it marvellous?!
       </h2>
    </div>
  );
}

export default App;

"Woah! HTML이 기능합니까? 이 광기는 무엇입니까?" HTML처럼 보이지만 실제로는 JSX (JavaScript XML)라고 합니다. 이를 통해 기본적으로 JavaScript와 HTML을 함께 사용할 수 있습니다.


조금 이상해 보일 수도 있습니다. 원래 HTML과 JavaScript (및 CSS)를 분리하여 프런트 엔드 개발을 배웠습니다. 

그러나 JavaScript와 앱 디자인 방식이 발전했으며 모든 것을 동일한 "구성 요소"로 유지하면 코드를 보다 쉽게 ​​유지 관리하고 재사용 할 수 있습니다.


이것을 실제로 봅시다. 터미널을 열고 실행


npm start

브라우저가 열리고 앱이 실행되고 있습니다.


축하합니다! 첫 번째 구성 요소를 만들었습니다.


JSX 


이 JSX에 대해 생각할 때 머리 위로 물음표가 떠오를 것입니다. 이것에 대해 자세히 살펴 보겠습니다.

  return (
    <div>
      <h1>Hello React World</h1>
      <h2>
          This is our first React App - isn't it marvellous?!
      </h2>
    </div>
  );

이것은 HTML처럼 보이지만 그렇지 않습니다. 이것은 JSX입니다! 일반적인 HTML처럼 보이지만 React가 다음 구문을 사용하여 요소 트리를 작성한다는 것입니다.


React.createElement(component, props, ...children)
  • component : 만들려는 HTML 요소 (예 : h1, div 등)
  • props : 해당 구성 요소에 전달하려는 props (나중에 props에 대해 이야기하겠습니다)
  • children :이 요소 내에 중첩 된 HTML 요소의 배열


따라서 방금 만든 동일한 구성 요소를 다음과 같이 작성할 수 있습니다.


const App = () => {
  return (
    React.createElement(
      "div",
      null,
      React.createElement("h1", null, "Hello React World"),
      React.createElement(
        "h2",
        null,
        "This is our first React App - isn't it marvellous?!"
      )
    )
  );
}

조금 불쾌하게 보입니다 (입력하려고 시도하는 것이 훨씬 나빴습니다). 주의 깊게 추적하면 props이 없는 div 요소가 생성되고 있음을 알 수 있습니다 (두 번째 인수로 null을 전달하여 표시됨). 마지막으로 createElement 구문 (H1 및 H2 요소)을 사용하여 2 개의 요소를 더 만듭니다.


한동안 자바 스크립트를 사용해 본 적이 있다면 document.createElement와 유사하다는 것을 알았을 것입니다. 그리고 그건! 이것은 결국 JavaScript 라이브러리입니다!


이것은 React에서 JSX의 장점입니다. 복잡한 React.createElement()를 사용하지 않고도 구문과 같은 HTML을 작성할 수 있습니다.


실제로 React 개발자는 거의 독점적으로 JSX를 사용하여 코드를 작성합니다. 아니요,이 섹션은 시간 낭비가 아니었습니다. 항상 어떤 일이 발생하는지 이해하는 것이 좋습니다. 지식은 힘입니다 (받은 편지함에 적은 질문이 있습니다)!


일을 역동적으로 만들기 


그래서 우리는 JSX를 보았고 그것에 대한 두려움을 극복했습니다. 하지만 요점이 뭐야? HTML을 사용할 수 있는데 왜 이 JSX를 사용합니까? 그들은 똑같아? 권리?


JSX가 무엇을 의미하는지 기억한다면 – JavaScript XML. 즉, JavaScript를 사용하여 사물을 동적으로 만들 수 있습니다. 이전 예제는 다음과 같습니다.


const App = () => {
  return (
    <div>
      <h1>Hello React World</h1>
      <h2>This is our first React App - isn't it marvellous?!</h2>
    </div>
  );
}

이제 텍스트를 보다 역동적으로 만들고 싶다고 가정하겠습니다. 먼저 메시지를 담을 변수를 추가하겠습니다 :


cont message = "This is my first variable rendered in JSX!" 


여기에 JavaScript를 추가하기 위해 ** 중괄호 **를 사용합니다.


const App = () => {
  const message = "This is my first variable rendered in JSX!";

  return (
    <div>
      <h1>Hello React World</h1>
      <h2>{message}</h2>
    </div>
  );
}

브라우저에서 이를 실행하면 메시지 변수의 텍스트가 나타납니다. 계속해서 메시지 변수 텍스트를 다른 것으로 바꾸고 마술이 일어나는 것을 지켜보십시오.


중괄호를 사용하여 컴파일러에 "이 코드를 JavaScript로 실행"이라고 지시합니다. 중괄호가 없다면 메시지 변수는 JavaScript로 실행되지 않고 대신 "메시지"라는 텍스트가 화면에 나타납니다. 이것을 시도하고 참조하십시오!


이벤트 처리 


이벤트를 처리 할 때도 동일한 방법을 사용할 수 있습니다. JSX를 사용할 때 React는 onClick, onPress, onSubmit 등 이미 익숙한 이벤트 리스너에 대한 액세스를 제공합니다.


메시지를 클릭 할 때 경고를 표시한다고 가정하겠습니다. 먼저 onClick 속성을 h2 태그에 추가합니다.


onClick 속성은 함수를 받아들입니다 (즉, 함수를 인수로 전달합니다.이 함수는 다음과 같이 경고를 호출합니다.


const App = () => {
  const message = "This is my first variable rendered in JSX!";  

  return (
    <div>
      <h1>Hello React World</h1>
      <h2 onClick={()=> alert("you clicked the message!")}>{message}</h2>
    </div>
  );
}

여기서 화살표 함수를 사용하여 멋지고 간결한 인라인 함수를 만드는 방법에 주목하십시오. 이 구문에 익숙하지 않은 경우 여기에서 자세히 다루는 내 책을 확인하십시오.


함수가 JavaScript로 실행되도록 이 코드를 중괄호 안에 넣은 방법에 다시 주목하십시오.


함수 호출 


마지막 예제에서 인라인 함수를 살펴 보았습니다. JSX는 JavaScript이므로 리턴 블록 외부에서 함수를 작성하고 참조 할 수 있습니다. 마지막 예는 다음과 같습니다.


const App = () => {
  const message = "This is my first variable rendered in JSX!";  

  const handleClick = () =>{
	alert("you clicked the message!");
  }

  return (
    <div>
      <h1>Hello React World</h1>
      <h2 onClick={handleClick}>{message}</h2>
    </div>
  );
}

메시지를 알리는 handleClick이라는 함수를 어떻게 만들었는지 주목하십시오. 인라인 함수를 사용하는 대신 onClick 속성에서 이 함수를 참조합니다. 이것을 시도하고 어떻게되는지보십시오.


다음은 JavaScript를 사용하여 동적으로 만드는 방법에 대한 몇 가지 예일뿐 아니라 JSX의 힘을 보여주기를 바랍니다. 우리는 나중에 모범을 보이면서 이해를 깊게 할 것입니다. 아직 이해가 되지 않는 것에 대해 걱정하지 마십시오!


구성 요소를 렌더링 하는 방법 


JSX에 관한 몇 가지 질문을 정리했으면 합니다. 다음으로 궁금한 점은 구성 요소가 어떻게 렌더링 됩니까? 어디? 언제?


처음부터 시작하겠습니다. 파일 구조를 다시 살펴보면 index.js 파일이 있습니다. 이것은 처음으로 실행되는 파일입니다 (우리는 이것을 "엔트리 포인트"라고 부릅니다). 이는 일반적으로 관례에 따라 다릅니다. 원하는 경우 진입 점을 변경할 수 있지만 지금은 그대로 둡니다.


파일을 파헤 치면 다음 줄이 표시됩니다.


ReactDOM.render(<App />, document.getElementById("root"));

document.getElementById (“root”) — 마지막으로 보이는 JavaScript입니다! 일반 ol 'JavaScript를 사용하여 DOM에서 루트 요소를 가져 와서 그 안에 앱 컴포넌트를 렌더링 합니다. 우리의 앱 컴포넌트는 다음과 같이 가져옵니다 :


import App from "./App"

App 컴포넌트를 App.js로 내보냈습니다. 이를 통해 다른 파일 / 컴포넌트가 앱 컴포넌트를 가져오고 사용할 수 있습니다.


루트 요소는 어디에서 왔습니까? 공용 폴더에 있는 index.html 파일을 기억하십니까? 이 index.html 파일은 웹 사이트가 로드 될 때 로드되는 첫 번째 HTML 파일입니다.


그 안에 우리는 ID가 root 인 div가 있으며 비어 있습니다. React가 컴포넌트를로드하는 곳입니다. 개발자 도구에서 이것을 살펴 보겠습니다.


Chrome (또는 사용 중인 브라우저)을 열고 개발 도구를 검사하십시오. 트리의 어딘가에 id =“root”인 div와 앱 구성 요소에서 렌더링 된 HTML이 표시됩니다. 정말 멋진!


id-root-dev-tools.png 



빠른 요약 



계속 진행하기 전에 지금까지 배운 내용을 빠르게 요약 해 보겠습니다.

  • 우리는 index.html 파일을 가지고 있는데, 이는 웹앱의 골격입니다.
  • 앱이 시작되면 index.html이 로드 되고 앱 구성 요소를 가져옵니다.
  • 앱 구성 요소의 JSX가 HTML로 변환 된 후 root div의 index.html 파일에 렌더링 됩니다.


연락처 목록을 만들 수 있습니다! 


이제 우리는 발을 React로 적시고, 서로 잘 어울리는 방법을 더 잘 이해 했으므로, 지금까지 배운 것을 사용하여 예제 애플리케이션을 구축해 보겠습니다. 또한 React를 시작하는 데 도움이 되는 몇 가지 일반적인 React 기능에 대해서도 알아 봅니다. 


연락처 목록에는 이름, 이메일, 연령 및 아바타 (또는 프로필 이미지)를 포함한 여러 연락처가 표시됩니다.


점진적으로 이를 구축하여 API에서 데이터를 가져옵니다. 얼마나 흥미 진진한!


contacts-list-intro.png 


스타일 가져 오기 


이 튜토리얼은 React 튜토리얼이므로 React의 내부 작업에 중점을 두고 멋진 스타일을 만드는 것에 대해 걱정하지 않습니다. 소스 폴더에서 새 파일 styles.css를 만들고 다음 코드를 붙여 넣습니다.


.contact-card {
  display: flex;
  padding: 10px;
  color: #ffffff;
  background-color: rgb(42, 84, 104);
  font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  box-shadow: 10px 10px 25px -16px rgba(0, 0, 0, 0.75);
  border-radius: 10px;
  max-width: 500px;
  max-height: 125px;
  margin-bottom: 10px;
}

.contact-card p {
  margin-left: 10px;
  margin-top: 0;
}

button {
  margin-left: 10px;
  margin-bottom: 10px;
}

다음으로 App.js로 이동하여 다음과 같이 스타일 시트를 가져옵니다.


import "./styles.css";

연락처 카드 만들기 


여전히 App.js에있는 동안 기본 JSX를 추가하여 연락처 카드의 레이아웃을 적용 해 보겠습니다. return 문에서 모든 것을 제거하고 다음을 추가하십시오.


<div className="contact-card">
	<img src="https://via.placeholder.com/150" alt="profile" />
	<div className="user-details">
		<p>Name: Jenny Han</p>
		<p>Email: Jenny.Han@notreal.com</p>
		<p>Age: 25</p>
	</div>
</div>

여기서 하는 일은 연락처 카드 세부 정보를 "랩핑"하는 div를 만들고 이미지를 추가하고 (이미지는 웹에서 가져온 자리 표시자를 사용함) 몇 가지 p 태그를 추가하여 필요한 세부 정보를 유지하는 것입니다. 연락처 카드. 마지막으로 styles.css에서 가져온 CSS 클래스를 추가합니다.


참고 : CSS 클래스를 참조하려면 className 키워드를 사용해야 합니다. JSX를 작성하고 있기 때문에 JavaScript에서 "class"는 예약어입니다.


App.js 파일에서 지금까지 얻은 내용은 다음과 같습니다.


import React from "react";
import "./styles.css";

const App = () => {
  return (
    <div className="contact-card">
      <img src="https://via.placeholder.com/150" alt="profile" />
      <div className="user-details">
        <p>Name: Jenny Han</p>
        <p>Email: Jenny.Han@notreal.com</p>
        <p>Age: 25</p>
      </div>
    </div>
  );
}

브라우저에서 이를 실행하면 다음과 유사한 내용이 표시됩니다.


contac-card-template.png 


재사용 가능한 연락처 카드 만들기 


우리 연락 카드를 가지고 있습니다! 그러나 재사용이 쉽지 않습니다. 카드를 두 개 이상 렌더링 하려면 이 코드를 재사용 해야 하므로 이 코드를 자체 구성 요소로 분리하는 것이 좋습니다.


참고 — 쉽게 따라하기 위해 App.js에 만드는 모든 구성 요소를 넣겠습니다. 실제 환경에서는 이러한 여러 구성 요소를 자체 파일로 분할하고 필요한 경우 가져 오거나 내보내는 것이 좋습니다.


App 함수 바로 아래에 ContactCard라는 새 함수를 만들고 JSX를 App에서 ContactCard로 복사합니다.


const ContactCard = () => {
  return (
    <div className="contact-card">
      <img src="https://via.placeholder.com/150" alt="profile" />
      <div className="user-details">
        <p>Name: Jenny Han</p>
        <p>Email: Jenny.Han@notreal.com</p>
        <p>Age: 25</p>
      </div>
    </div>
  );
};

React의 컴포넌트는 JSX를 반환하는 함수일 뿐입니다. JSX를 ContactCard로 옮겼으므로 이 구성 요소를 기본 앱 구성 요소 내에서 사용할 수 있습니다.


const App = () => {
  return (
    <>
      <ContactCard />
    </>
  );
}

이전 HTML / JSX 태그와 같은 자체 구성 요소를 사용합니다. 컴포넌트 이름을 꺾쇠 괄호 안에 넣습니다. App.js 파일은 다음과 같아야 합니다.


// App.js
import React from "react";
import "./styles.css";

const App = () => {
  return (
    <>
      <ContactCard />
    </>
  );
};

const ContactCard = () => {
  return (
    <div className="contact-card">
      <img src="https://via.placeholder.com/150" alt="profile" />
      <div className="user-details">
        <p>Name: Jenny Han</p>
        <p>Email: Jenny.Han@notreal.com</p>
        <p>Age: 25</p>
      </div>
    </div>
  );
};

이제 브라우저에서 이것을 실행하면 이전과 똑같이 보일 것입니다. 이것이 우리가 원하는 것입니다. 우리는 이제 우리가 원하는 만큼 사용할 수 있는 ContactCard 컴포넌트를 가지고 있습니다 :


const App = () => {
  return (
    <>
      <ContactCard />
      <ContactCard />
      <ContactCard />
    </>
  );
};

다른 2 ContactCard 구성 요소를 포함하도록 App 구성 요소를 업데이트하십시오. 위의 예는 브라우저에서 3 개의 연락처 카드를 렌더링 합니다. 가서 확인해보세요!



이것을 페이지의 "스탬프"처럼 생각하십시오. 우리가 추가하는 모든 ContactCard 구성 요소는 다른 "스탬프"이며 페이지에서 동일한 마크 업을 렌더링 합니다. 



state에 대해 이야기하자 – useState Hook 


이미 React를 시작했다면 State라는 말을 들었을 수 있습니다. State는 React에서 상당히 큰 문제입니다. 그래서 무엇입니까?


상태는 기본적으로 UI가 "React" 변경할 수 있는 앱의 일부를 나타내는 객체입니다. 상태는 무엇이든 될 수 있습니다. 객체, 부울, 배열, 문자열 또는 정수 


예를 들어 봅시다.


연락처 목록에 나타나는 일부 사람들은 부끄러워서 버튼을 클릭 할 때까지 나이를 표시하고 싶지 않습니다. 컴포넌트 내에서 useState 후크를 사용하여 연령을 표시해야 하는지 여부를 저장할 수 있습니다. 이것은 다음과 같습니다


const [showAge, setShowAge] = useState(false);

"대체 무슨 일이 일어나고 있는 거야?" 설명하겠습니다.


useState 객체는 현재 값을 가진 변수와 그 값을 변경할 수 있는 함수를 제공합니다. useState를 호출하면 초기 값을 정의 할 수 있습니다 (이 경우 false).


우리는 이것을 얻기 위해 useState 훅에 구조적 할당을 사용합니다. 당신은 지금 구조적 할당하는 것에 대해 걱정할 필요가 없습니다. 첫 번째 변수는 우리가 상태 값에 접근하게 하고, 두 번째 변수는 우리가 그것을 바꿀 수 있다는 것을 기억하십시오.


다음과 같이 ContactCard 구성 요소에 위의 코드 스니펫을 추가하십시오.


const ContactCard = () => {
  const [showAge, setShowAge] = useState(false);

  return (
    <div className="contact-card">
      <img src="https://via.placeholder.com/150" alt="profile" />
      <div className="user-details">
        <p>Name: Jenny Han</p>
        <p>Email: Jenny.Han@notreal.com</p>
        <p>Age: 25</p>
      </div>
    </div>
  );
};

이제 상태 객체가 있는데 어떻게 사용합니까? 다른 변수와 마찬가지로 showAge 변수를 참조 할 수 있습니다. 이 경우 showAge 변수가 true 인 경우 _only 연령 만 표시하려고 합니다.


삼항 연산자를 사용하여 이 작업을 수행 할 수 있습니다.


{showAge === true ? <p>Age: 25</p> : null}

이 예제는 showAge 변수가 true 인 것처럼 읽으며, 그렇지 않으면 렌더링 하지 않습니다.


다음과 같이 ContactCard 구성 요소에 추가하십시오.


const ContactCard = () => {
  const [showAge, setShowAge] = useState(false);

  return (
    <div className="contact-card">
      <img src="https://via.placeholder.com/150" alt="profile" />
      <div className="user-details">
        <p>Name: Jenny Han</p>
        <p>Email: Jenny.Han@notreal.com</p>
        {showAge === true ? <p>Age: 25</p> : null}
      </div>
    </div>
  );
};

이제 브라우저에서 앱을 실행하면 연령이 사라지는 것을 볼 수 있습니다. 이는 showAge 변수가 false로 초기화 되었기 때문입니다. showAge 변수를 true로 초기화하면 :


const [showAge, setShowAge] = useState(true);

연락처 카드에 나이가 나타납니다. 좋은! 별로 좋지는 않지만 연락처 카드에 연령을 표시 할 때마다 코드를 변경하고 싶지 않습니다.


showAge 변수를 동적으로 변경하는 방법을 살펴보기 전에 코드를 정리하십시오. 계속해서 이 줄을 바꾸십시오 :


{showAge === true ? <p>Age: 25</p> : null}
{showAge && <p>Age: 25</p> }

이것은 더 간결한 방식으로 동일한 결과를 제공합니다.


팁 : 이해하기 쉬운 코드를 줄이십시오. 작성하는 모든 코드 줄을 단축해야 할 필요는 없습니다! 가독성이 우선입니다. 


상태 업데이트 


업데이트 상태로 돌아갑니다. 다시 기억한다면 useState() 후크는 상태를 업데이트하는 함수를 제공합니다. 이 버튼을 버튼에 연결하여 클릭하면 연락처 카드의 연령 표시를 토글 합니다.


우리는 다음과 같이 할 수 있습니다.


<button onClick={() => setShowAge(!showAge)}>
	Toggle Age 
</button>

이 작업은 showShow의 값을 현재 상태와 반대로 변경하기 위해 setShowAge 함수 (useState 후크에서 가져옴)를 호출하는 것입니다.


우리는 다음과 같이 할 수 있습니다.


<button onClick={() => setShowAge(!showAge)}>
	Toggle Age 
</button>

이 작업은 showShow의 값을 현재 상태와 반대로 변경하기 위해 setShowAge 함수 (useState 후크에서 가져옴)를 호출하는 것입니다.


참고 : 여기서는 화살표 함수 구문을 사용하여 onClick 속성에 함수를 전달합니다. 익숙하지 않은 경우 [[React here]에서 알아야 할 중요한 JavaScript 부분에 대해 논의하는 서적]을 얻을 수 있음을 알려드립니다. 


상태가 업데이트 되면 React는 컴포넌트를 다시 렌더링하며 showAge의 값이 true이므로 연령이 표시됩니다.


사용자가 버튼을 다시 클릭하면 showAge가 false로 설정되고 React가 컴포넌트를 다시 렌더링 하며 연령이 숨겨집니다.


age-toggle.gif 


우리의 멋진 토글을 보십시오!


팁 : 구성 요소 상태가 변경 될 때마다 React는 새 상태로 구성 요소를 다시 렌더링 합니다.


ContactCard 구성 요소가 3 개 렌더링 되는 경우에도 단추를 클릭하면 에이지가 카드 중 하나에 만 표시되고 일부는 표시되지 않습니다. 상태는 개별 구성 요소에 속하기 때문입니다. 즉, 렌더링 하는 각 ContactCard 구성 요소는 복사본이며 자체 상태 / 데이터가 있습니다.


Props 소개 


이제 몇 차례 재사용 할 수 있는 멋진 새 ContactCard 구성 요소가 생겼습니다. 실제로 재사용 할 수는 없지만 이름, 이메일, 연령 및 아바타는 각 구성 요소마다 동일하므로 이런! props라는 것을 사용하여 이 데이터를 보다 역동적으로 만들 수 있습니다.


방금 React를 시작했기 때문에 Props를 구성 요소에 전달되는 데이터로 생각하면 구성 요소가 사용할 수 있습니다. 예를 들어 아바타, ** 이메일 **, 이름 및 연령을 연락처 카드 구성 요소에 소품으로 전달할 수 있습니다.


<ContactCard
  avatar="https://via.placeholder.com/150"
  name="Jenny Han"
  email="jenny.han@notreal.com"
  age={25}
/>

보시다시피, 이름을 지정하여 소품을 정의합니다. 예 : 이름과 등호를 사용하여 해당 소품에 값을 할당하십시오. 제니 한


원하는 만큼 props을 가질 수 있으며 원하는 대로 이름을 지정할 수 있으므로 매우 유연합니다.


props은 문자열, 숫자, 부울, 객체, 배열 등과 같은 다양한 유형의 데이터를 보유 할 수 있습니다.


참고 : props은 인용 텍스트 (예 : name =“Jenny Han”) 또는 중괄호 (예 : age = {25})를 사용하여 정의해야 합니다. 문자열 이외의 다른 중괄호를 생략하면 항목이 깨지기 시작합니다 (age = 25). 


계속해서 앱 구성 요소 내의 현재 ContactCard 구성 요소를 다음과 같이 바꾸십시오.


<ContactCard
  avatar="https://via.placeholder.com/150"
  name="Jenny Han"
  email="jenny.han@notreal.com"
  age={25}
/>

<ContactCard
  avatar="https://via.placeholder.com/150"
  name="Jason Long"
  email="jason.long@notreal.com"
  age={45}
/>

<ContactCard
  avatar="https://via.placeholder.com/150"
  name="Peter Pan"
  email="peter.pan@neverland.com"
  age={100}
/>

여기서 하는 일은 구성 요소에 필요한 데이터를 props으로 각 구성 요소에 전달하는 것입니다. 각 구성 요소마다 데이터가 어떻게 다른지 확인하십시오.


컴포넌트 내 props 사용 


우리는 ContactCard 구성 요소에 props을 많이 보냈으므로 ** ContactCard **에 사용 방법을 알려 드리겠습니다.


지금까지 ** ContactCard ** 기능은 매개 변수를 허용하지 않습니다. 마법 같은 반응 인 React는 모든 props을 자동으로 멋진 props 객체에 넣고 구성 요소에 전달합니다.


const ContactCard = props => {
	//...other code
};

props 변수를 주목하십시오. 이것은 이전에 정의한 props을 포함하는 객체입니다. 다음과 같이 점 표기법을 사용하여 정의 된 props에 액세스 할 수 있습니다.


const ContactCard = props => {
	console.log(props.avatar); 
	console.log(props.name);
	console.log(props.email);
	console.log(props.age);

	//...other code
};

마지막으로 JSX의 하드 코딩 된 값을 소품에서 받은 값으로 바꾸려고 합니다.


return (
  <div className="contact-card">
    <img src={props.avatar} alt="profile" />
    <div className="user-details">
      <p>Name: {props.name}</p>
      <p>Email: {props.email}</p>
      <button onClick={() => setShowAge(!showAge)}>Toggle Age </button>
      {showAge && <p>Age: {props.age}</p>}
    </div>
  </div>
);

소props에서 받은 값을 사용하여 이미지 소스를 설정 한 방법에 주목하십시오. 

이름, 이메일 및 연령에 대해서도 비슷했습니다. 또한 이 코드를 중괄호로 묶는 방법을 살펴보면 JavaScript로 실행됩니다.


마지막 App.js 파일은 다음과 같습니다.


// App.js
const App = () => {
  return (
    <>
      <ContactCard
        avatar="https://via.placeholder.com/150"
        name="Jenny Han"
        email="jenny.han@notreal.com"
        age={25}
      />
      <ContactCard
        avatar="https://via.placeholder.com/150"
        name="Jason Long"
        email="jason.long@notreal.com"
        age={45}
      />
      <ContactCard
        avatar="https://via.placeholder.com/150"
        name="Peter Pan"
        email="peter.pan@neverland.com"
        age={100}
      />
    </>
  );
};

const ContactCard = props => {
  const [showAge, setShowAge] = useState(false);

  return (
    <div className="contact-card">
      <img src={props.avatar} alt="profile" />
      <div className="user-details">
        <p>Name: {props.name}</p>
        <p>Email: {props.email}</p>
        <button onClick={() => setShowAge(!showAge)}>
			Toggle Age 
		</button>
        {showAge && <p>Age: {props.age}</p>}
      </div>
    </div>
  );
};

브라우저에서 이것을 실행하면 다음과 비슷한 것을 볼 수 있습니다 :


contact-lists-3-components.png 


우리의 구성 요소는 이전과 동일하지만 더 역동적입니다. 레이아웃, 스타일 및 상태 개체를 동일하게 유지하면서 동일한 ContactCard를 재사용 할 수 있지만 다른 데이터를 전달할 수 있습니다.


리스트에서 컴포넌트 렌더링 


우리의 연락처 목록이 잘 나오고 있습니다. 잘 만들어진 재사용 가능한 코드가 있습니다. 잘못된! 한 걸음 더 나아가 봅시다.


실제 응용 프로그램에서 데이터는 일반적으로 데이터 배열 형태로 제공됩니다 (예 : API 호출 후. 데이터베이스에서 일부 사용자를 검색하기 위해 API 호출을 하고 다음 데이터를 수신했다고 가정 해 보겠습니다.


const contacts = [
    { name: "Jenny Han", email: "jenny.han@notreal.com", age: 25 },
    { name: "Jason Long", email: "jason.long@notreal.com", age: 45 },
    { name: "Peter Pan", email: "peter.pan@neverland.com", age: 100 }
];

이것을 함수 상단의 App() 구성 요소에 붙여 넣습니다. 당신의 독수리 눈은 이 데이터가 우리가 이미 가지고 있는 것과 어떻게 비슷한 지 알 수 있습니다. 

그러나 이 데이터를 ContactCard 구성 요소로 어떻게 전환 할 수 있습니까? 글쎄, 당신이 .map()을 사용하여 배열을 반복하는 법을 배우는 요즘을 기억하십니까? 지금 우리가 그 일을 시작한 날입니다!


구성 요소 목록을 표시하려면 다음을 수행하십시오.


  1. .map()을 사용하여 배열을 반복
  2. 배열의 각 항목에 대해 새 ContactCard 구성 요소를 작성하십시오.
  3. 배열의 각 객체의 데이터를 소품으로 ContactCard 구성 요소에 전달


이것이 어떻게 작동하는지 봅시다. appApp() 컴포넌트에서 return 문을 다음으로 바꿉니다 :


return (
  <>
    {contacts.map(contact => (
      <ContactCard
        avatar="https://via.placeholder.com/150"
        name={contact.name}
        email={contact.email}
        age={contact.age}
      />
    ))}
  </>
);

보시다시피, 우리는 배열을 매핑합니다. 배열의 각 개체에 대해 새 ContactCard 구성 요소를 만들고 싶습니다. 소품의 경우 map 함수가 있는 현재 객체의 이름, 이메일 및 연령을 가져와야 합니다. 즉, 접촉 변수에서.


참고 : 현재 '아바타' prop은 그대로 두었습니다. 나중에 자습서에서 변경 될 예정입니다. 


App.js 파일은 다음과 같습니다.


//App.js
const App = () => {
  const contacts = [
    { name: "Jenny Han", email: "jenny.han@notreal.com", age: 25 },
    { name: "Jason Long", email: "jason.long@notreal.com", age: 45 },
    { name: "Peter Pan", email: "peter.pan@neverland.com", age: 100 },
    { name: "Amy McDonald", email: "amy@email.com", age: 33 }
  ];

  return (
    <>
      {contacts.map(contact => (
        <ContactCard
          avatar="https://via.placeholder.com/150"
          name={contact.name}
          email={contact.email}
          age={contact.age}
        />
      ))}
    </>
  );
};

브라우저에서 이것을 실행하면 모양이 동일해야 합니다. 우리는 ContactCard를 변경하지 않고 데이터를 가져온 위치 만 변경했습니다. 이것에 대한 멋진 점은 연락처 배열에 다른 행을 추가하면 추가 구성 요소가 자동으로 렌더링 되므로 다른 작업을 수행 할 필요가 없다는 것입니다. 직접 시도해보십시오.


API에서 데이터 가져 오기 


멋진 React 앱이 생겼습니다. 역동적이고 일이 잘되고 있습니다. React를 시작한 이후로 좋은 장소입니다! 그러나 우리는 약간의 정리가 필요합니다. 실제 응용 프로그램에서는 데이터가 API에서 가져옵니다.


이 튜토리얼의 다음 부분에서는 실제 API (https://randomuser.me/)에서 실제 연락처 (실제 연락처를 말할 때 가짜 연락처를 의미합니다)를 가져옵니다. 웹 사이트를 탐색하고 응답을 살펴보십시오. 여기서 데이터를 구성 요소에 채울 수 있습니다.


먼저 API에서 가져온 데이터를 보유 할 상태 변수를 만들어 보겠습니다. 상태는 변화 할 수 있는 것을 유지하는 데 좋습니다. 연락처 목록은 확실히 바뀔 수 있습니다!


App.js에서 연락처 배열을 제거하고 다음을 추가하십시오.

const [contacts, setContacts] = useState([]);

여기서는 상태 객체를 만들어 빈 배열로 초기화합니다. API 호출시 연락처 목록을 포함하도록 상태를 업데이트합니다. 이 상태 객체 접점의 이름을 지정 했으므로 JSX 내의 렌더링 논리는 방금 삭제 한 기존 접점 배열과 달리 이 배열을 대신 찾습니다.


다음으로 API에서 데이터를 가져옵니다. 표준 Fetch API를 사용합니다. 지금은 콘솔에 데이터를 기록합니다. 방금 만든 상태 객체 아래에 다음을 추가하십시오.


fetch("https://randomuser.me/api/?results=3")
  .then(response => response.json())
  .then(data => {
    console.log(data);
  });

우리가 여기서 하는 일은 :


  • randomuser API에 GET 요청을 하여 세 가지 결과 요청
  • 응답을 JSON으로 변환
  • JSON을 콘솔에 로깅


브라우저에서 이 기능을 실행하면 ContactCard 구성 요소가 더 이상 렌더링 되지 않습니다. 이제 새 데이터를 상태에 저장하지 않았으며 상태 변수가 현재 비어 있습니다. 

브라우저 (도구 개발 도구)에서 콘솔을 보면 응답 개체가 기록 된 것을 볼 수 있습니다. 다음과 같이 보일 것입니다.


response_object.png 


3 개의 객체가 있는 결과 배열이 표시됩니다. 이러한 각 개체에는 사용자의 세부 정보가 포함됩니다 (또는 이 경우 "연락처"). 이것은 이전 섹션에서 직접 생성 한 연락처 배열과 유사합니다. 객체로만 구성된 배열입니다.


이 객체에서 데이터를 선택하도록 앱 컴포넌트 JSX를 업데이트하겠습니다. 다음과 같이 JSX를 업데이트하십시오.


return (
  <>
    {contacts.map(contact => (
      <ContactCard
        avatar={contact.picture.large}
        name={contact.name.first + " " + contact.name.last}
        email={contact.email}
        age={contact.dob.age}
      />
    ))}
  </>
);

이것은 우리가 전에 했던 것과 비슷하게 작동합니다.


  • 우리는 연락처 변수를 통해 반복하고 있습니다 (현재 빈 배열입니다)
  • 응답을 상태 (다음 단계)에 저장하면 배열의 각 객체를 살펴보고 필요한 적절한 항목 (이 경우 그림, 이름, 전자 메일 및 dob 객체)을 찾습니다.


다음으로 결과 배열을 상태로 저장하려고 합니다. 따라서 JSX는 (이전에 본 map() 함수를 사용하여) 루프를 반복하고 멋진 ContactCard를 렌더링 할 수 있습니다. fetch 함수 내에서 다음과 같이 setContacts(data.results)에 대한 호출을 추가하십시오.

fetch("https://randomuser.me/api/?results=3")
  .then(response => response.json())
  .then(data => {
    console.log(data);
    setContacts(data.results);
  });

우리의 앱 컴포넌트는 다음과 같습니다 :

//App.js
const App = () => {
  const [contacts, setContacts] = useState([]);

fetch("https://randomuser.me/api/?results=3")
  .then(response => response.json())
  .then(data => {
    console.log(data);
    setContacts(data.results);
  });

  return (
    <>
      {contacts.map(contact => (
        <ContactCard
          avatar={contact.picture.large}
          name={contact.name.first + " " + contact.name.last}
          email={contact.email}
          age={contact.dob.age}
        />
      ))}
    </>
  );
};

저장하고 브라우저에서 실행하면 다음과 같은 내용이 표시됩니다.


multiple-calls-to-api.gif 


“WTF가 진행되고 있습니까? 모든 것이 깨졌습니다!”


아직 당황하지 마십시오. (더 느린 컴퓨터에 있거나 약간 당황한 경우, 현재 페치 기능에서 setContacts (data.results) 행을 주석 처리 할 수 ​​있습니다).


여기서 일어나는 일은 우리가 약간의 고리에 갇혀 있다는 것입니다.


  1. 데이터를 가져 와서 다시 가져 오기 위해 전화를 겁니다.
  2. 그런 다음 이 데이터를 상태로 저장합니다
  3. React는 상태가 변경되면 다시 렌더링 합니다.
  4. 컴포넌트가 다시 렌더링 되면 페치 API 호출이 다시 발생하고 상태를 설정합니다.
  5. 상태가 업데이트 된 후 구성 요소가 다시 렌더링 됩니다.
  6. 컴포넌트가 다시 렌더링 된 후 페치가 다시 호출됩니다.
  7. 당신은 아이디어를 얻는다

그럼 어떻게 막을까요? 내장 된 다른 React Hook-useEffect로 이 문제를 해결할 수 있습니다.


useEffect 소개 


useEffect 후크는 기능을 실행하는 특수 후크입니다. 기본적으로 useEffect 후크는 다시 렌더링 할 때마다 실행됩니다. 그러나 특정 조건에서만 실행되도록 구성 할 수 있습니다 (예 : 구성 요소가 마운트 될 때 또는 변수가 변경되는 경우 useEffect 후크는 다음과 같습니다.


useEffect(() => {
	// code to run 
});

이것은 매번 실행됩니다. "한 번만 실행"을 지정하려면 빈 배열을 두 번째 인수로 전달합니다.


useEffect(() => {
	// code to run 
},[]); //<-- notice the empty array

이것을 종속성 배열이라고 합니다. 종속성 배열이 비어 있으면 구성 요소를 처음 로드 할 때만 useEffect 함수가 실행됩니다. 추가 렌더링의 경우 useEffect 기능을 건너 뜁니다.


컴포넌트가 로드 될 때 데이터를 한 번만 가져 오려고 하므로 API 호출을 하기에 완벽한 장소입니다. 계속해서 ** useEffect () ** 함수를 App 컴포넌트에 넣고 페치 API 호출을 useEffect 함수로 이동하십시오. 우리의 앱 컴포넌트는 다음과 같습니다 :


//App.js
const App = () => {
  const [contacts, setContacts] = useState([]);

  useEffect(() => {
    fetch("https://randomuser.me/api/?results=3")
      .then(response => response.json())
      .then(data => {
        setContacts(data.results);
      });
  }, []);

  return (
    <>
      {contacts.map(contact => (
        <ContactCard
          avatar={contact.picture.large}
          name={contact.name.first + " " + contact.name.last}
          email={contact.email}
          age={contact.dob.age}
        />
      ))}
    </>
  );
};

이제 브라우저에서 코드를 실행하면 3 개의 연락처 카드가 나타납니다! 다른 무작위 연락처 목록을 보려면 페이지를 새로 고치십시오.


contacts-list-intro.png 


결론 


축하합니다! 방금 첫 번째 실제 앱을 완성하고 더 발전된 주제로 넘어갈 수 있는 토대를 마련했습니다.



페이지 정보

조회 21회 ]  작성일20-05-23 15:46

웹학교