나의 개발일지

[React] 불변성 / 카운터 만들기 / styling 본문

React

[React] 불변성 / 카운터 만들기 / styling

heew0n 2023. 11. 2. 20:59

 

불변성을 지키는 것이 중요하다!

 

불변성은 메모리의 있는 값을 변경할 수 없는 것을 말한다

 

자바스크립트의 원시 데이터는 문자열, 숫자, 불리언 타입 등이 있는데

우선 결론적으로 말하자면 원시데이터는 불변성이 있다

반대로 원시데이터가 아닌 배열, 객체, 함수는 불변성이 없다!

 

 

<원시 데이터>  ▶ 불변성이 있다!

 

let num = 1; 

 

메모리에는 1이 라는 값이 저장되고 , num이라는 변수는 메모리에 있는 1을 참조!

 

그리고 재선언

 

let num2 = 1;

 

num === num2 의 결과값은 true이다!

 

즉, num의 메모리 주소에 이미 1이라는 값이 할당이 되었고

같은 값으로 재선언을 해도 메모리 주소가 변하지 않고 이미 생성되어 있는

1이라는 값을 참조한다!

--> 같은 메모리 값을 바라보고 있는 것이다

 

 

즉, 기존 메모리에 저장이 되어 있는 1이라는 값이 변하지 않고, 새로운 메모리 저장공간에 2가 생기고 number라는 값을 새로운 메모리 공간에 저장된 2를 참조하게 됩니다.

 

 


 

 

데이터를 수정했을 경우

 

let num = 1을 let num = 2로 수정

원시데이터는 불변성을 가지고 있기 때문에 기존 메모리의 1이 변하지 않고 새로운 메모리에 2를 저장하여 참조한다

원시데이터는 수정을 했을 때 메모리에 저장된 값 자체는 바꿀 수 없고, 새로운 메모리 저장공간에 새로운 값을 저장한다 

 

 


 

 

 

<원시데이터가 아닌 것(배열, 객체, 함수)> ▶ 불변성이 없다!

 

obj1 = {name: 'park'}

 

메모리에 obj가 저장된다

 

그리고 같은 값을  재선언

 

obj2 = {name: 'park '}

 

obj1 === obj2 의 값은 false이다

새로운 obj2라는 메모리 공간에 저장이 된다.

 

 

 


 

 

 

데이터를 수정했을 경우

obj2 = {name: 'park '}에서 'kim'으로 수정

객체는 불변성을 가지고 있지 않다.  기존 메모리의 name : 'park'을 name : 'kim'으로 바뀌어 버린다

원시데이터가 아닌 데이터는 수정했을 때 기존에 저장되어 있던 메모리 저장공간의 값 자체를 바꿔버린다

 

 

 

 

 

 

 


 

실습 예제 - 카운터 만들기

 

-1 누르면 위에 숫자가 1씩 감소,

+1 누르면 위에 숫자가 1씩 증가하는 카운터 만들기

 

 

import React, { useState } from "react";

function App() {
  const [count, setCount] = useState(0);

  const minusOnclickHandler = function () {
    const minusNewCount = count - 1;
    setCount(minusNewCount);
  };

  const plusOnclickHandler = function () {
    const plusNewCount = count + 1;
    setCount(plusNewCount);
  };

  return (
    <div>
      <div>
        <div>{count}</div>
        <button onClick={minusOnclickHandler}>-1</button>
        <button onClick={plusOnclickHandler}>+1</button>
      </div>
    </div>
  );
}

export default App;

 

 

어제 배운 input과 button 이 있어서 막 어렵진 않았다

하지만 증감하는 함수 만드는 게 조금 어려웠다

 

 ** 꼭 주의해야 할 것은 인라인으로 함수 만들지 않기!

 


styling

 

 

 

 

 

▼ App.js

 

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

function App() {
  return (
    <div className="plants">
      <p>감자</p>
      <p>고구마</p>
      <p>오이</p>
      <p>가지</p>
      <p>옥수수</p>
    </div>
  );
}

export default App;

 

 

 

▼ App.css

 

p {
  border: 1px solid green;
  margin: 20px;
  height: 100px;
  width: 100px;
  align-items: center;
  border-radius: 10%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.plants {
  display: flex;
  flex-direction: row;
  text-align: center;
  justify-content: center;
}

 

위에 있는 이미지처럼 만들어보라고 해서

난 p태그에 한 번에 묶어서 만들었는데

더욱 좋은 방법이 있었다


 

 

▼map() 사용하기

 

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

function App() {
  const testArr = ["감자", "고구마", "오이", "가지", "옥수수"];

  return (
    <div className="app-style">
      {testArr.map(function (item) {
        return <div className="component-style">{item}</div>;
      })}
    </div>
  );
}
export default App;

 

 

(CSS 생략)

map함수를 써서 배열의 각 요소를 가공할 수 있다

** 참고로 map 함수는 모든 요소를 다 순회하고 출력한다

 


 

 

▼ filter 함수로 원하는 값을 제거하기

 

//filter 함수
import React from "react";
import "./App.css";

function App() {
  const testArr = ["감자", "고구마", "오이", "가지", "옥수수"];

  return (
    <div className="app-style">
      {testArr
        .filter(function (item) {
          return item !== "오이"; //조건
        })
        .map(function (item) {
          return <div className="component-style">{item}</div>;
        })}
    </div>
  );
}
export default App;

 

 

(CSS 생략)

item의 "오이" 값을 제외한 조건의 새로운 배열을 반환하고 

그 배열에 다시 map 함수를 써서 component를 호출한다!

(너무 신세계임)

 


 

▼ "오이"를 제외한 배열 렌더링

 

 


 

 

▼ input 이름 , input  나이에 사용자가 입력한 값이 밑에 추가되는 기능 구현하기 

 

 

 

 

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

const App = function () {
  const [users, setUsers] = useState([
    { id: 1, age: 5, name: "토끼" },
    { id: 2, age: 12, name: "강아지" },
    { id: 3, age: 8, name: "고양이" },
    { id: 4, age: 7, name: "너구리" },
  ]);
  const [name, setName] = useState("");
  const [age, setAge] = useState("");

  const nameChangeHandler = function (event) {
    setName(event.target.value);
  };

  const ageChangeHandler = function (event) {
    setAge(event.target.value);
  };
  const clickAddHandler = function () {
    const newUser = {
      id: users.length + 1,  //지금 users 배열의 숫자 값에 +1
      name: name, // key와 value가 같으면 생략가능!! 
      age   // 여기도 같으니 생략
    };
    
    //불변성을 유지하기 위해 풀어주고 뒤에 새로운 값을 추가한다.
    setUsers([...users, newUser]);
  };
  return (
    <div>
      <div>
        이름 : <input value={name} onChange={nameChangeHandler} />
        <br />
        나이 : <input value={age} onChange={ageChangeHandler} />
        <br />
        <button onClick={clickAddHandler}>추가</button>
      </div>
      <div className="app-style">
        {users.map(function (item) {
          return (
            <div className="component-style">
              {item.age} - {item.name}
            </div>
          );
        })}
      </div>
    </div>
  );
};

export default App;

 

 

 

배열 users를 바꿀 수 있는 방법은 setUsers!

setUsers([...users, newUser]);

 

스프레드 문법 (...) 으로 배열 [  ]을 풀어주고

그 뒤에 새로운 값을 추가하는 새로운 배열을 만든다!

 

 

 

 

 

 


 

 

▼ map 함수 사용시 key 값 오류

 

 

이런 오류 창이 뜬다면 유니크한 key 값이 필요하다

key = {} 만 추가해주면 된다.

 

<div key={item.id} className="component-style">
              {item.age} - {item.name}
            </div>

 

 

 


 

내일은 오늘 배웠던 거 혼자 직접 해볼 예정이다!

그리고 내일 리액트 진도 끝내고 복습 열심히 할 것이다~