본문 바로가기
개발공부/리액트

React(2) 리액트 state & onClick 사용법 (reference data type을 곁들인)

by 보라색두부찌개 2023. 6. 10.

목차

1. 기본사용법

2. state사용법

3. onClick 사용법

4. state변경하는 방법


기본 사용법

자, Visual Studio Code에 React를 작성해보자!

필자는 zreact폴더에, w1라는 프로젝트를 진행

※ 폴더 설명
- node_modules 폴더 : 라이브러리 코드 보관함
- public 폴더 : htm파일이나 img파일 임시적으로 저장하고 싶을때, static파일 모아 놓는곳
- src 폴더 : 주로 우리가 코드 짜는곳

※ 파일 설명
- src폴더에, App.js : 이 쪽에 코드를 짤것이다. 이것이 우리의 메인 페이지!
- src폴더에, App.css : 이 쪽은, css와 동일하다!
- "기본 홈페이지 틀인 index.html에, 우리가 다룰 App.js를 집어넣어 주세요" 라는 행동을 index.js가 해주고 있음
- package.json : 프로젝트정보

 

  • App.js의 function App(){}밖에 여러 함수나 변수 선언하고, return ()에 보여줄 것들을 코딩하면 된다!

 

 

  • return안에, 평소 html 타이핑 하듯이 하면 되는데, 몇가지 차이점이 있다.
  1. Class 대신! ClassName이라고 써야한다.
    이유: 자바스크립트가 기본이므로, class 사용법과 혼동됨
  2. 변수넣을땐 {변수명}로 사용한다.
    -> getElementId등 일련의 과정 대신, 그냥 {변수명}으로 가능! 거의 모든곳에 넣을 수 있다.
    ex) <h4> 안녕{a}야</h4>
    -> 데이터바인딩이라고함
  3. css사용할 때, css파일에말고, 인라인 style sheet에 넣으려면,
    태그에다가 style = { {color : 'red', fontSize : "16px"} } 타이핑 하면 된다.
    (이때, font-Size가 아님 주의 -> 리액트에서 -는 마이너스임)

  • 블로그를 만든다고 가정하고, 꾸며보자.
    (화면 하단의 JavaScript 클릭 후, react로 변경하면 코드 자동완성 기능이 활성화 된다.)

자동완성 기능(1)
자동완성 기능(2)
자동완성 기능(3)
이러한 글을 포스팅하는 블로그를 작성한다고 치자

  • 이름의 내용이 변수에 따라 바뀌게끔 하려면 우리가 흔히 사용하는 변수로

let name = "사나";
  • 이렇게 할당해도 되겠지만, 변수가 바뀜에 따라서 홈페이지 값을 변경하려면, "리렌더링(화면에서의 데이터 값들을 갱신) 해주세요!"
    라는 코드를 일일히 실행시켜야 한다.
    하지만, React에서는 State가 변경되었을 때마다 리렌더링이 자동으로 되므로,
    변경이 자주될 것 같은 변수가 있다면 state라는 기능을 쓰는 것이 옳다.

State에 대해서

  • state를 사용하려면, import를 해야하는데, useState라는 것을 코드에 치면 맨 위 코드에 자동완성이 될 것이다.
    (안된다면, import { useState } from 'react'; 을 직접 타이핑하자)
    사용법은
let [state명, state를변경하는함수명] = useState(초기값)

이 되겠다.

** 이 때 이것을 Destructuring 문법 이라고 일컫음 : let [a, c] = [1, 2] -> 문법을 동일시해서 씀

▶ state를 활용하여, 반복되는 내용의 레이아웃을 작성해보자!

 

더보기
import "./App.css";
import { useState } from 'react'

function App() {
  let [face, face_change] = useState(["이쁘지", "귀엽지", "사랑스럽지"])
  return (
    <div className="App">
      <div className="nav_bar">
        <span>Harrys blog</span>
      </div>

      <div className="list">
        <h3>안녕 나는 카즈하야</h3>
        <span> 엄청 {face[0]} </span>
      </div>
      <div className="list">
        <h3>안녕 나는 김채연이야</h3>
        <span> 엄청 {face[1]} </span>
      </div>
      <div className="list">
        <h3>안녕 나는 장규리야</h3>
        <span> 엄청 {face[2]} </span>
      </div>
    </div>
  );
}
warning 없애는 법 : eslint-disalbe
-> error는 고치면 안돌아가는 주요한 사항이지만,
warning은, "너 변수 이러이러하게 선언해놨는데 안썼어. 너 F야?"라고 알려주는거라 무시해도 되긴 한다.

onClick에 대해서

  • onClick은 특정 요소에서 발생하는 이벤트를 처리하기 위한 이벤트 핸들러 중 하나 이다.
  • onClick안에는 "함수"만 들어가야한다.
    이때,
  • 1. 태그에 직접, 함수를 호출해도 되고, ()=>{}형식
import "./App.css";
import { useState } from 'react'

function App() {
  return (
    <div className="App">
      <span onClick={ () => {
        alert("안녕!")
      }}>👍</span>
    </div>
  );
}

export default App;

 

  • 2. 태그에 직접, 함수를 선언하고 바로 호출 해도 되고, onClick = function(){}형식
import "./App.css";
import { useState } from 'react'

function App() {
  return (
    <div className="App">
      <span onClick={ function(){
        alert("안녕!")
      }}>👍</span>
    </div>
  );
}

export default App;

 

  • 3. 함수를 위에 선언해놓고, 호출만 태그안에서 해도 된다. onClick ={ sayHi }형식
import "./App.css";
import { useState } from 'react'

function sayHi(){
  alert("안녕!");
}
function App() {
  return (
    <div className="App">
      <span onClick={sayHi}>👍</span>
    </div>
  );
}

export default App;

 

 


 

state 변경하는 방법에 대해서

state변경함수명(바꿀 state값)
이 때, array/object 다룰때 원본은 보존하는게 좋다 : 나중에 원본 데이터 필요할 때 곤란할 수 도 있음.
★★★ javascript의 reference data type과 state함수의 알아야 할 점!
state변경함수의 특징
-> state변경함수는, 기존 state == 신규 state인 경우 바꾸지 않는다.
array, object등 reference data type의 특징
-> let arr = [1,2,3]이라고 한다면, arr변수는, 주소값을 가리키고, 그 주소값을 따라간 메모리상에는 [1,2,3]이 저장되어있음.
( ex) arr[0] = "a"라고 바꾼다면 arr이 가리키고있는 메모리에는 ["a", 2, 3]이 존재하고 있음.)

state변경함수의 특징과 reference data type의 특징이 만나 끔찍한 혼종의 시나리오!!
-> let [name, change_name] = useState(["harry", "james"])가 위에 선언되어있다고 치자.
-> 버튼을 누른다면 name의 "harry"값을 "potter"값으로 변경하려고 한다.
-> array/object 다룰때 원본은 보존하는게 좋다는 말을 믿고, 
import "./App.css";
import { useState } from 'react'

function App() {
  let [name, change_name] = useState(["harry", "james"])
  return (
    <div onClick={ ()=>{
      let tmp = name;
      tmp[0] = "potter";
      change_name(tmp);
    }}>
      {name[0]}
    </div>
  );  
}
export default App;

이라고 한다면, 작동하지않는다.
-> 왜? : let tmp = name;이라는 코드에서, tmp는 name과 이름만 다르지,
name이 가리키고 있는 주소값그대로 가져온다.
따라서, 그 상태에서 change_name()함수를 실행할 때, 컴퓨터는,
"엥 tmp와 name이 가리키고있는 주소값이 같잖아? change_name안해도 되겠네! 안행!"
이라고 하게된다.
-> 따라서,
- 아예 다른 값을 가진 변수로 지정을 해주든지 :  let tmp = ["harry", "james"];
(같은 값이 들어가 있지만, 주소값은 다른 state이다)

import "./App.css";
import { useState } from 'react'

function App() {
  let [name, change_name] = useState(["harry", "james"])
  return (
    <div onClick={ ()=>{
      let tmp = ["harry", "james"]
      tmp[0] = "potter"
      change_name(tmp);
    }}>
      {name[0]}
    </div>
  );  
}
export default App;


(이렇게 한다면, 짜칠뿐더러, 타이핑하기 긴 변수라면 비효율적일 것 이다!)
- ...함수를 사용하여, 다른 값을 가진 변수로 지정이 된것처럼 저장을 해보자 : let tmp = [...name];
(...함수는, "array에 있던 대괄호를 벗겨주세요"라는 함수이다. 그 상태에서 다시 []로 씌우니, 컴퓨터는 "새로운 state"구나!"라고 인식하게 된다.)

import "./App.css";
import { useState } from 'react'

function App() {
  let [name, change_name] = useState(["harry", "james"])
  return (
    <div onClick={ ()=>{
      let tmp = [...name];
      tmp[0] = "potter";
      change_name(tmp);
    }}>
      {name[0]}
    </div>
  );  
}
export default App;

▶ 여러가지 state로 구성된 홈페이지에서, 버튼을 누르면, state들이 변경되면서 글씨들이 한번에 바뀌는 홈페이지를 만들어 보자!

더보기
import "./App.css";
import { useState } from 'react'

function App() {
  let [face, face_change] = useState(["이쁘지", "귀엽지", "사랑스럽지"])
  let [thumb, thumb_change] = useState(0)
  return (
    <div className="App">
      <div className="nav_bar">
        <span>Harry's blog</span>
      </div>

      <div className="list">
        <h3>안녕 나는 카즈하야</h3>
        <span> 엄청 {face[0]} </span>
        <span onClick={()=>{
          face_change(["미쳤지", "엄청나지", "러블리하지"])
          }}>👍</span>
        <span>{thumb}</span>
      </div>
      <div className="list">
        <h3>안녕 나는 김채연이야</h3>
        <span> 엄청 {face[1]} </span>
      </div>
      <div className="list">
        <h3>안녕 나는 장규리야</h3>
        <span> 엄청 {face[2]} </span>
      </div>
    </div>
  );  
}
export default App;

 

▶ 여러가지 state로 구성된 홈페이지에서, 버튼을 누르면, 여러 글들이 가나다순으로 정렬되는 홈페이지를 만들어 보자!

더보기
import "./App.css";
import { useState } from 'react'

function App() {
  let [face, face_change] = useState(["ㄴ이쁘지", "ㄱ귀엽지", "ㄷ사랑스럽지"])
  return (
    <div className="App">
      <div className="nav_bar">
        <span>Harry's blog</span>
      </div>

      <div className="list">
        <h3>안녕 나는 카즈하야</h3>
        <span> 엄청 {face[0]} </span>
        <span onClick={()=>{
          let temp = [...face]
          face_change(temp.sort())
          }}>👍</span>
      </div>
      <div className="list">
        <h3>안녕 나는 김채연이야</h3>
        <span> 엄청 {face[1]} </span>
      </div>
      <div className="list">
        <h3>안녕 나는 장규리야</h3>
        <span> 엄청 {face[2]} </span>
      </div>
    </div>
  );  
}
export default App;