#2-3 The Basics of React/State(1)

강서현·2022년 8월 13일
0

MovieWeb

목록 보기
1/1

React JS는 웹사이트를 interactive하게 만든다.
이를 알아보기 위해, 클릭을 위한 버튼 하나와 클릭 수를 출력하는 텍스트로 이루어진 사이트를 작성한다.

Vanilla JS

<!DOCTYPE html>
<html>
<body>
    <span>Total clicks: 0</span>
    <button id="btn">Click me</button>
</body>
<script>
    let counter = 0; //클릭 수를 세기 위해 counter 변수를 선언한다.
    const button = document.getElementById("btn"); //btn id의 버튼을 가져온다.
    const span = document.querySelector("span"); //span 태그를 가져온다.
    function handleClick(){ //클릭 시 실행할 함수를 작성한다.
        counter=counter+1 // counter 변수를 1 증가시킨다.
        span.innerText = `Total clicks: ${counter}`; // span 태그를 변경한다. 
    }
    button.addEventListener("click",handleClick) //click event를 감지한다.
</script>

</html>

코드 양이 많기 때문에, 이를 아래와 같이 개선할 수 있다.

React

<!DOCTYPE html>
<html>
<body>
    <div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script> 
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

<script type="text/babel">
    function App() { 
        const [counter, setCounter] = React.useState(0); 
        const onClick = () => {
            setCounter((current) => current + 1);
        }
        return(
            <div>
                <h3>Total clicks : {counter}</h3>
                <button onClick={onClick}>Click me!</button>
            </div>
        );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root); 
</script>
</html>

위의 코드를 도출하는 방법은 아래 단계를 따른다.

1. React Element 사용하기

리액트를 import하기 위해 본 강의에서는 아래 두 개 링크를 사용했다.

<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script> 
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>

리액트를 사용해 화면에 Hello, I'm a span. 이라는 텍스트를 띄우기 위해서는 아래와 같이 작성할 수 있다.

<!DOCTYPE html>
<html>
<body>
    <div id="root"></div> <!--root 생성-->
</body>
  
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script> 
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<!--React JS는 요소 생성을 돕는 라이브러리, React-DOM은 이를 body태그에 넣어준다.-->

<script>
    const root = document.getElementById("root"); //root 가져오기
    const span = React.createElement( //Element를 생성한다.
        "span",  //argument1. 해당 Element는 span이다. --> 오타 주의
        {id: "sexy-span", style: { color: "red" }}, //argument2. property는 다음과 같다.
        "Hello, I'm a span" //argument3. content
    );
    ReactDOM.render(span, root); //요소들을 React DOM을 사용해 span을 root에 렌더링 하기.
</script>
</html>

React의 기본 구조(sript->HTML)이 반영되어

2. Event

아래는 console 창에 문구를 띄우는 텍스트와 버튼을 생성하는 코드이다.
각각 onMouseEnter와 onClick 이벤트에 해당하며, 다음과 같이 작성할수 있다.

<!DOCTYPE html>
<html>
    <body>
        <div id="root"></div>
         
    </body>
    <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> 
    <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
    <script>
        const root = document.getElementById("root");
        const h3 = React.createElement(
            "h3", 
            {onMouseEnter: () => console.log("im mouse")},
            // 화살표 함수를 이용해 마우스를 가져다 대면 im mouse 출력한다.
            "Hello, I'm a span"
        ); 
        const btn = React.createElement(
            "button", 
            {onClick: () => console.log("im clicked"),
            // 화살표 함수를 이용해 클릭하면 im clicked 출력한다.
            style: {
                backgroundColor: "tomato",
                }},
            "Click me!"); 
        const container = React.createElement("div", null, [h3, btn]);
        // 복수의 요소를 출력하기 위해 container 생성
        ReactDOM.render(container, root); 
    </script>
</html>

이제 버튼 클릭에 필요한 이벤트를 추가할 수 있다.
그러나 여전히 createElement를 사용한다.

3. JSX

<!DOCTYPE html>
<html>
    <body>
        <div id="root"></div>
         
    </body>
    <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> 
    <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel">
        const root = document.getElementById("root");
        const Title = (
            <h3 id="title" onMouseEnter={() => console.log("mouse enter")}> 
                Hello, I'm a title!
            </h3>
        );
        const Button = (
            <button
                style={{
                    backgroundColor: "tomato",
                }}
                onClick={() => console.log("im clicked")}
            >
                Click me!
            </button>
        );
        const container = React.createElement("div", null, [Title, Button]);
        ReactDOM.render(container, root); 
    </script>
</html>

위의 코드는 2번 문항과 완전히 동일하게 작동하지만, Babel을 통해 JSX(대충 JS->HTML) 코드를 사용할 수 있다.
container까지 변환하면 아래와 같은 형태가 된다.

<script type="text/babel">
    const root = document.getElementById("root");
  
    const Title = () => ( // 함수로 변환
        <h3 id="title" onMouseEnter={() => console.log("mouse enter")}> 
            Hello, I'm a title!
        </h3>
    );
    const Button = () =>  ( // function+return
        <button
            style={{
                backgroundColor: "tomato",
            }}
            onClick={() => console.log("im clicked")}
        >
            Click me!
        </button>
    );
    const Container = ( //첫 글자를 대문자로
        <div>
            <Title /> //Title과 Button을 태그처럼 사용
            <Button /> // *주의: 컴포넌트의 첫 글자는 대문자
        </div>
        );
    ReactDOM.render(Container, root); 
</script>

4. Understanding State

현재까지 배운 것으로 처음의 click counter를 만들면 아래와 같다.

<script type="text/babel">
    const root = document.getElementById("root");
    let counter = 0;

    function countUp() { // a. counter의 값을 1 올려준다.
        counter = counter + 1   
        render();
    }

    function render() { //b. 재렌더링
        ReactDOM.render(<Container />, root); 
    }

    const Container = () => ( 
        <div>
            <h3>Total clicks : {counter}</h3> //counter 값 대입
            <button onClick={countUp}>Click me!</button>
            // c. 버튼 클릭 이벤트
        </div>
        );
    ReactDOM.render(<Container />, root); // d. 렌더링
</script>

b의 과정이 없으면 업데이트가 되지 않기 때문에, 값이 화면에 반영되지 않는다.
버튼을 누르면 c->a->b 순으로 재렌더링이 일어난다.
이때, vanilla JS와는 다르게 counter 값 자체만 업데이트됨을 알 수 있다.

보다시피, 렌더링 하는 것을 잊게 되면 문제가 생긴다. 이 과정이 번거롭기 때문에, 아래와 같이 다시 작성할 수 있다.

5. setState

useState를 사용하면 렌더링을 편리하게 할 수 있는데, 과정은 아래와 같다.

<!DOCTYPE html>
<html>
    <body>
        <div id="root"></div>
         
    </body>
    <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> 
    <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <script type="text/babel">
        const root = document.getElementById("root");
        function App() { 
        const [counter, setCounter] = React.useState(0); 
      	//countUp 대체, 배열->배열
        const onClick = () => {
            setCounter(counter + 1);
      		//modifier가 counter 값을 해당 값으로 바꾸고 렌더링
            }
            return(
                <div>
                    <h3>Total clicks : {counter}</h3>
                    <button onClick={onClick}>Click me!</button>
                </div>
            );
        }
        
        ReactDOM.render(<App />, root); 
    </script>
</html>

6. State Functions

위의 코드도 제대로 기능하기는 하지만, 앞으로 있을 문제들을 미리 방지하기 위해 아래와 같이 작성할 수 있다.

<script type="text/babel">
       function App() { 
           const [counter, setCounter] = React.useState(0); 
           const onClick = () => {
               setCounter((current) => current + 1);
 				//setCounter(counter+1);과 동일, 더 안전
           }
           return(
               <div>
                   <h3>Total clicks : {counter}</h3>
                   <button onClick={onClick}>Click me!</button>
               </div>
           );
       }
       const root = document.getElementById("root");
       ReactDOM.render(<App />, root); 
   </script>

현재의 값을 바탕으로 다음 값을 설정할 때는 위와 같이 함수의 형식으로 작성한다.

여기까지가 Vanilla JS로 작성된 Click Counter를 React로 변환하는 과정이다.

0개의 댓글