본문 바로가기
리액트

[react] 예제로 따라하는 리액트 훅(hook) - useState

by jaewooojung 2019. 8. 2.

ReactJS


결과물1
결과물2
결과물3


useState

간단한 예시를 통해서 리액트 훅의 useState을 살펴보겠습니다.

위의 사진들처럼 화면 아래쪽에 3개의 동그란 버튼을 누르면, 화면 중앙의 정사각형이 해당하는 버튼의 색으로 변경되는 예입니다.

 

프로젝트 설치단계부터 하나씩 진행하겠습니다.

리액트에 처음 입문하시는 분들도 천천히 따라 해보시길 바랍니다.

 

create-react-app으로 프로젝트를 설치합니다.

npx create-react-app hooks-react

 

저는 에디터로 Visual Studio code를 사용하겠습니다.

 

code 명령어로 프로젝트를 실행합니다.

code hooks-react

 

 

기본화면을 지우기 위해 src폴더에서 App.js와 index.js를 제외한 모든 파일을 지워줍니다.

프로젝트 폴더

 

스타일 작업을 위해 styled-components를 설치하겠습니다.

styled-components에 관한 설명은 아래 글을 참조해 주세요

2019.07.30 - [react] 스타일드 컴포넌트(styled components)

 

[react] 스타일드 컴포넌트(styled components)

1. Styled-components? styled-components는 react와 react-native에서 스타일을 적용하는 데 사용되는 라이브러리입니다. styled-components 없이 전통적인 CSS 방식(css 혹은 scss 임포트)으로 애플리케이션에 스타일을

codingbroker.tistory.com

 

css나 다양한 css 전처리기를 사용하셔도 좋습니다. 다만 그대로 따라 하시려면 styled-components를 설치해 주세요!

css 파일을 따로 관리하면 props에 따라 조건부 랜더링을 할 때 css 클래스를 여러 개 생성하고 적용해줘야 하는 불편함이 있습니다.

 

styled-components 설치

npm install styled-components

 

설치 후 프로젝트를 실행해 줍니다.

npm run start

 

App.js에서 styled-components와 useState을 불러옵니다.

 

 

index.js와 App.js의 초기상태는 다음과 같습니다.

index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

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

 

App.js

import React, { useState } from "react";
import styled from "styled-components";

function App() {
  return <Container>App</Container>;
}

const Container = styled.div``;

export default App;

 

App에서 Container를 생성하였습니다.

 

다음으로 App 컴포넌트에 배경색상이 적용될 Pallete클릭했을 때 배경색을 변경시키는 Button들을 만들겠습니다.

 

App.js

import React, { useState } from "react";
import styled from "styled-components";

function App() {
  return (
    <Container>
      <Pallete />
      <ButtonContainer>
        <CyanButton />
        <BrownButton />
        <PinkButton />
      </ButtonContainer>
    </Container>
  );
}

const Container = styled.div`
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
`;

const Pallete = styled.div`
  width: 700px;
  height: 700px;
  border: 1px solid black;
`;

const ButtonContainer = styled.div`
  margin-top: 50px;
  width: 700px;
  display: flex;
  justify-content: center;
`;

const Button = styled.button`
  margin: 0 5px;
  width: 100px;
  height: 100px;
  border-radius: 50px;
  outline: none;
  border: none;
  cursor: pointer;
`;

const CyanButton = styled(Button)`
  background: cyan;
`;

const BrownButton = styled(Button)`
  background: brown;
`;

const PinkButton = styled(Button)`
  background: pink;
`;

export default App;

 

실행화면

 

기본 틀이 완성되었습니다.

 

다음으로 아래쪽 3가지의 버튼을 클릭했을 때 각각 해당되는 버튼의 색상이 Pallete의 배경색이 되도록 구현하겠습니다. 이를 구현하기 위해서는 색상 데이터가 저장될 변수가 필요합니다.

 

리액트에서는 이렇게 사용자와 상호작용을 하거나 값에 따라서 화면에 변화를 주는 데이터를 state으로 관리합니다.

 

state을 선언하기 위해 useState을 사용합니다.

App.js

import React, { useState } from "react";
import styled from "styled-components";

function App() {
  const [color, setColor] = useState("black");
  return (
    <Container>
      <Pallete />
      <ButtonContainer>
        <CyanButton />
        <BrownButton />
        <PinkButton />
      </ButtonContainer>
    </Container>
  );
}

...

 

useState은 길이가 2인 배열을 반환합니다.

 

첫 번째 요소는 state,

두 번째 요소는 state을 변경시키는 함수입니다.

 

즉, 위 코드의 useState 호출 부분은 아래 코드와도 같습니다.

const color = useState("black")[0];
const setColor = useState("black")[1];

useState의 인자로 전달한 값("black")은 state의 초기값입니다.

 

state의 이름은 자유롭게 지을 수 있습니다.

단, apple이라는 이름으로 지었으면 그 state을 변경시키는 함수이름은 관습적으로 setApple과 같이 set으로 시작하고 camelCase를 적용해 줍니다.

 

이제 state을 Pallete로 전달해 주겠습니다.

App.js

...

function App() {
  const [color, setColor] = useState("black");
  return (
    <Container>
      <Pallete color={color} />
      <ButtonContainer>
        <CyanButton />
        <BrownButton />
        <PinkButton />
      </ButtonContainer>
    </Container>
  );
}

...
const Pallete = styled.div`
  width: 700px;
  height: 700px;
  border: 1px solid black;
  background: ${props => props.color};
`;

 

Pallete에 color값을 전달해 주었습니다.

Pallete에서는 받은 color를 위와 같이 화살표 함수의 형태로 사용할 수 있습니다.

 

실행화면

 

배경화면이 적용되었습니다.

state의 초기값을 black으로 생성했기 때문에 검은색으로 변경된 것을 확인하실 수 있습니다.

 

다음으로 버튼을 클릭했을 때 해당 색상으로 배경화면이 바뀌는 코드를 구현해 보겠습니다.

 

현재 App 컴포넌트의 color가 Pallete로 전달되면서 배경화면이 출력되고 있으니

버튼을 클릭했을 때 App 컴포넌트의 color를 변경해 주면 Pallete의 배경화면도 바뀌게 됩니다.

 

이렇게 color state이 변화하면 화면에서 color state을 사용하고 있는 부분이 자동으로 다시 그려집니다.

=> 리랜더링

 

먼저 버튼에 이벤트 핸들러를 달아줍니다.

 

App.js의 Container

<Container>
  <Pallete color={color} />
  <ButtonContainer>
    <CyanButton onClick={() => setColor("cyan")} />
    <BrownButton onClick={() => setColor("brown")} />
    <PinkButton onClick={() => setColor("pink")} />
  </ButtonContainer>
</Container>

useState을 통해 생성된 setColor 함수를 사용했습니다.

 

onClick 이벤트 핸들러는 해당 요소가 클릭되었을 때 주어진 콜백함수를 실행합니다.

주의할 점은 위와 같이 인자를 넘겨주는 함수를 달아줄 때에는 값을 화살표 함수로 주어야 한다는 것입니다.

 

만약 

onClick={ setColor("cyan") }

이렇게 함수 그 자체를 전달하면 컴포넌트가 화면에 그려지면서 setColor함수가 바로 실행되어 버리기 때문에

[렌더링 -> state변경 -> 변경으로 인한 렌더링 -> state변경... ]와 같은 무한루프에 빠지게 됩니다.

 

프로젝트 실행 후 버튼을 클릭해 보겠습니다.

 

버튼을 클릭할 때마다 해당 색상으로 color state이 바뀌면서 화면에 적용됩니다.



        
답변을 생성하고 있어요.