[Front-end] 개발자 공부

[개발 공부 33일차] Counter 구현

MOLLY_ 2024. 2. 6. 18:43
728x90

 

어제 저녁부터 오늘 새벽까지 React 입문 강의 전체 다시 듣고, 중요한 코드는 따라 작성하며 공부했다. 중간중간 나오는 과제는 영상을 멈춘 다음에 내가 직접 코드를 처음부터 끝까지 작성했다. 맞혔을 때는 기분이 매우 좋았고 확실히 공부도 더 잘 되는 게 체감되었다.

 

 

< 목차 >

1. React 입문 복습 및 코드

2. Counter 코드 및 다짐

3. 금일 소감

 

 

 

1. React 입문 복습 및 코드

입문 강의 보면서 만든 것

 

 

입문 강의를 다시 들으며 위와 같이 만들었다. 주차별로 어떤 걸 배웠고 기억해야 할 것은 무엇인지 다시 정리하며 코드를 작성하니 이해도도 높아지고 코드를 직접 작성할 수 있다는 자신감도 형성됐다.

 

그리고 확실히 지금까지 공부를 잘못된 방향으로 했다는 걸 확실하게 깨달았다. 이렇게 공부하니까 시간도 크게 안 들고 또 쉽게 이해가 됐기 때문이다. 내일부터 팀 프로젝트 시작인데 얼른 남은 시간 집중해서 최대한 팀 프로젝트에서 내가 맡은 기능의 코드도 내 손으로 직접 작성할 수 있게끔 실력을 끌어올려야 한다.

 

 

▼  React 입문 복습하며 작성한 코드

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

function App() {

  // [React 입문 과제] 1-6주차: 컴포넌트 소개
  const onClickAppBtn = () => {
    alert("App 버튼이 실행되었습니다!")
  }

  // [1-7주차 부모-자식 컴포넌트] 문제: 3개의 컴포넌트를 만들고 할아버지, 엄마, 자식 컴포넌트를 만든 뒤 서로 연결
  // [1-9주차 props의 개요] props를 통해 부모에서 자식으로 값을 내려줌
  // 단방향으로 내려줌
  function Son(props) {
    return <div>나는 {props.grandFatherName}의 손자예요</div>
  };

  function Mother(props) {
    const grandFatherName = props.gfName
    return <Son grandFatherName={grandFatherName} />
  };

  function GrandFather() {
    const name = "장성규";
    return <Mother gfName={name} />
  };

  // [1-8주차 JSX]
  const number = 11;

  const pTagSt = {
    color: "red",
  }


  // [1-10주차 Props children] children 문법으로 props 내려주기
  // 받은 props는 {props.children} 필수임
  function Father() {
    return <Daughter>Children 문법 Test</Daughter>
  }

  function Daughter(props) {
    // console.log(props.children)
    // 여기서 {props.children을 항상 내보내면 부모 컴포넌트에서 작성하는
    // 내용이 이 자식 컴포넌트에서 안에서 출력됨
    return <div> 자식 컴포넌트 {props.children} </div>
  }


  // [1-11주차 Props 추출] 구조분해할당
  const testObj = {
    name: "이상혁",
    age: 29,
    group: "T1",
  }

  const { name, age, group } = testObj;
  // console.log(name, age, group);


  // [1-12, 1-13주차 State] State 사용 목적: UI를 바꾸기 위해서
  const [id, setId] = useState("");
  const [pw, setPw] = useState("");

  const onIdChangeHandler = (event) => {
    setId(event.target.value);
  }

  const onPwChangeHandler = (event) => {
    setPw(event.target.value);
  }

  const onClickLoginBtn = () => {
    alert(`고객님이 입력하신 id는 ${id}이며,
    비밀번호는 ${pw}입니다.`)
    setId("")
    setPw("")
  }


  // [1-14주차 불변성 & 순수함수]
  // 불변성: 메모리에 있는 '값을 변경할 수 없는' 것
  // 원시 데이터: 숫자, 문자, boolean(참: 1, 거짓: 0)
  // => 바라보는 주소값 변화 있음
  let num = 1;
  let secondNumber = 1;
  console.log(num === secondNumber); // true

  // 원시 데이터가 아닌 것들: 배열, 객체, 함수
  // => 바라보는 주소값 변화 없음 (값 바꾸면 냅다 새로운 주소 만들어버림)
  const obj1 = {
    lastName: "Kim"
  }

  const obj2 = {
    lastName: "Kim"
  }

  console.log(obj1 === obj2); // false

  // 화면을 렌더링할지를 State의 변화에 땨라 결정함 (단순 let 어쩌고 하는 변수는 무시)
  const [hope, setHope] = useState({
    sleepTime: "none",
  });

  // [1-15주차 Component & Rendering]
  // 렌더링이 발생하는 경우: state가 변경됐을 때, 컴포넌트에 새로운 props가 들어올 때, 상위 컴포넌트에서 렌더링 발생했을 때

  // [1-16주차 카운터 앱 구현] 실습
  const [count, setCount] = useState(0)

  const onCountChangeHandler = (event) => {
    setCount(event.target.value);
  }

  const onClickPlusHandler = () => {
    setCount(count + 1);
  }

  const onClickMinusHandler = () => {
    setCount(count - 1);
  }

  // [1-17, 1-18주차 Styling, map] 실습
  // map: 원래 data를 개수만큼 가공해서 출력
  const items = ["감자", "고구마", "오이", "가지", "옥수수"];

  // [1-19주차 반복되는 컴포넌트 분리: map] 실습
  const [users, setUsers] = useState([
    { id: 1, name: "이상혁", age: 27 },
    { id: 2, name: "대상혁", age: 29 },
    { id: 3, name: "페이커", age: 20 },
    { id: 4, name: "Faker", age: 24 }
  ]);

  const [name2, setName2] = useState("");
  const [age2, setAge2] = useState("");

  const onName2ChangeHandler = (event) => {
    setName2(event.target.value)
  };

  const onAge2ChangeHandler = (event) => {
    setAge2(event.target.value)
  }

  // 추가 버튼 클릭
  const onClickAddBtnHandler = () => {
    const newUsers = {
      id: users.length + 1,
      name: name2,
      age: age2,
    }
    setUsers([...users, newUsers]);
  }


  // [1-20주차 반복되는 컴포넌트 분리] 삭제
  // 삭제 버튼 클릭
  const onClilkRemoveBtnHandler = (id) => {
    users.filter(user => user.id !== id)
  }




  return (

    <div style={{
      height: '100vh',
      display: ' flex',
      flexDirection: 'column',
      justifyContent: 'center',
      alignItems: 'center',
    }} >

      {/* 1-6주차 실습 */}
      <div>이건 App 컴포넌트입니다.</div>

      {/* 1-7주차 실습 */}
      <GrandFather />

      {/* 1-8주차 실습! *중요* return문 안에 JS 쓰려면 중괄호로 감싸기 */}
      <p style={pTagSt}>
        {
          number > 10
            ? number + "은 10보다 큽니다"
            : number + "은 10보다 작습니다"
        }
      </p>

      {/* 1-10주차 실습 */}
      <Father />
      <Daughter><div>children 문법: return 스코프에서 부모 컴포넌트로 감싸면
        부모 컴포넌트 아래로 똑같은 형태의 페이지를 만들 수 있음</div>
      </Daughter>

      {/* [1-11주차 Props 추출] 구조분해할당 */}
      <Child name={name} age={age} group={group} />
      <button onClick={onClickAppBtn}>Click!</button>

      {/* [1-13주차 State] 실습 - 로그인창 구현*/}
      {/* input 말고 <form/> 태그 사용하는 법 알아보기. data 관리하기 더 편하다고 함 */}
      {/* submit: 입력받은 데이터를 서버로 전송 | action: 전송할 서버 페이지 주소 지정 */}
      아이디: <input type="text"
        value={id}
        onChange={onIdChangeHandler} ></input>
      패스워드: <input type="password"
        value={pw}
        onChange={onPwChangeHandler}></input>
      <button onClick={onClickLoginBtn}>Login</button>

      {/* [1-14주차 불변성 & 순수함수] 실습 */}
      <div>{
        JSON.stringify(hope)}</div>
      <button onClick={() => {
        hope.sleepTime = "다 하면 2시간 잘 수 있음";
        const hope2 = { ...hope };
        setHope(hope2);
      }}>님 소원 들어드림</button>

      {/* [1-16주차 카운터 앱 구현] 실습 */}
      <div
        value={count}
        onChange={onCountChangeHandler}>{count}</div>
      <button onClick={onClickMinusHandler}>-</button>
      <button onClick={onClickPlusHandler}>+</button>

      {/* [1-17, 1-18주차 Styling, map] 실습 */}
      <div className="stItem">
        {
          items.filter((list) => {
            return list !== "가지";
          })
            .map((item) => {
              return <div key={item} className="stSquare">{item}</div>
            })
        }
      </div>

      {/* [1-19주차 반복되는 컴포넌트 분리: map] 실습 */}
      <div>
        이름: &nbsp; <input
          value={name2}
          onChange={onName2ChangeHandler} /> <br />
        나이: &nbsp; <input
          value={age2}
          onChange={onAge2ChangeHandler} />
      </div>
      <button onClick={onClickAddBtnHandler}>추가하기</button>
      <div className="stItem">{
        users.map((user) => {
          return (
            <div key={user.id} className="stSquare">{user.name}: {user.age}
              {/* [1-20주차 반복되는 컴포넌트 분리] 삭제 버튼 구현 */}
              <button onClick={() => onClilkRemoveBtnHandler(user.id)}>삭제</button>
            </div>
          )
        })}
      </div>
    </div>
  )
}

export default App

 

 

 

2. Counter 코드 및 다짐

Counter를 구현하는 코드를 작성했다.

 

import React from 'react'
import { useState } from 'react';

// 카운터인데... 카운터가 여러 개인.. 특정 배열의 1, 2, 3, 4.. 현황판
// +, -랑 전체 개수 나오는 거 분리


function App() {
  const testArr = [1, 2, 3, 4];
  const [count, setCount] = useState(0);

  const minusClickHandler = () => {
    setCount(count - 1);
  }

  const plusClickHandler = () => {
    setCount(count + 1);
  }

  return (
    <div>
      {
        testArr.map((item) => {
          return (<>
            <div key={item}>{count}
            <button
              onClick={minusClickHandler} >-</button>
            <button
              onClick={plusClickHandler}>+</button></div>
          </>)
        })
      }

    </div>
  )
}

export default App

 

 

 

잠을 안 자서 집중이 안 돼가지고 강의의 마지막 수정 기능을 안 봤는데, 그 타격이 컸다. 아는 연산자인데 어디다가 작성해야 할지 몰라서 헤맸다. 하지만 내가 아는 데까지는 코드를 안 보고 작성 가능했기 때문에 좀만 더 공부하면 가능하리라는 생각이 든다. 일단 오늘은 CRUD 구현을 10분 이내로 하는 걸 목표로 공부할 생각이다.

 

 

▼  정답 코드

import React from 'react'
import { useState } from 'react';

function App() {
  const [counts, setCounts] = useState([0, 0, 0, 0]);

  const minusClickHandler = (index) => {
    setCounts(counts.map((count, i) => i === index ? count - 1 : count))
  }

  const plusClickHandler = (index) => {
    setCounts(counts.map((count, i) => i === index ? count + 1 : count))
  }

  return (
    <div>
      {counts.map((count, index) => {
        return <div key={index}>
          <div>{count}</div>
          <button onClick={() => plusClickHandler(index)}>+</button>
          <button onClick={() => minusClickHandler(index)}>-</button>
        </div>
      })}
    </div>
  )
}

export default App

 

 

보면 정말 간단한 코드다. 이번 주까지 폭발적으로 성장하지 않으면 절대 안 된다. 할 수 있는 한까지 최대한 초몰입해서 혼자서 뚝딱뚝딱 금방 만들어낼 수 있게 해야겠다. 정답 코드랑 내 코드랑 비교해서 복습하는 시간 갖고, To-do list 만들어야겠다. 오늘은 강의 듣지 않고 가능한 한 많이, 처음부터 만들어서 그냥 자동적으로 코드가 써지게 해야겠다.

 

 

 

3. 금일 소감

React를 들어간 뒤로는 하루가 다르게 진도가 빨라서 잠깐 멈칫 하거나 공부하는 방향이 조금이라도 잘못되면 뒤로 쭉 밀려나는 것 같다. 자바스크립트 때, 일단 input을 많이 넣고 강의를 여러 번 반복해서 들으라는 얘기를 많이 들어서 지금껏 최대한 그래왔는데 이건 올바른 답이 아니었다. 최대한 많이 작성해보고 코드 예문을 많이 보는 게 실력이 느는 데에 최고의 방법이자 방향인 것 같다. 맨 첫 주차에서는 이 방식으로 했었고 그 덕분에 그 주차에서는 이해도도 높았던 것 같다.

 

하지만 그 이후부터는 타 동기생의 조언을 차용해서 적용하며 공부하다 보니 나한테는 맞지 않는 방식이었고 코딩 공부는 이렇게 하면 안 된다는 걸 알게 되는 한 달이었다. React를 진입한 지 3주 정도 되었는데 코드를 작성하는 것은 진입한 지 4~5일 된 실력인 것 같다.

 

늘 실력을 늘리는 데에 집중해야 하는 건 맞고 조급함을 느껴서 긴장감을 가져야 하는 것도 맞지만 그때그때 내 실력이 어느 정도고 올바른 방향과 방법으로 공부 중인지를 체크하는 것은 정말 중요한 것 같다. 아직 늦지 않았으니 이번 설 연휴까지 포함해서 React 숙련을 마스터 하고도 남게끔, 달리는 게 아니라 나는 수준으로 빡세게 공부하고 코드를 작성해 볼 생각이다.

 

'지금껏 내가 한 공부는 무엇이었는가' 하는 회의가 계속 느껴지는데, 그건 그것대로 추후에 내게 큰 도움이 될 것이라고 생각하고 있다. 당장 큰 도움이 되지는 않는 것이 이론 공부인 듯하다. 하지만 어려운 개념과 이론을 조금이라도 뇌에 더 친숙하게끔 미리 접해두는 것과 아닌 것은 큰 차이가 진다고 생각하기 때문에 너무 그동안의 내 노력을 깎아내리거나 허망하게 생각하지 않으려고 한다.

 

지금이라도 효과적이면서 올바른 방향과 방법을 알았으니 그에 맞게 극극극한으로 더더더 집중하면 된다. 파이팅!

 

728x90