yarn으로 리액트 앱 시작

soo's·2023년 4월 14일
0

TIL

목록 보기
36/53
post-thumbnail

0. yarn으로 리액트 시작하기

터미널에서 내가 작업을 진행할 폴더로 이동한 뒤, yarn create react-app week_1 명령어를 통해 week_1이라는 폴더가 새로 생서되고 그 안에 react-app이 설치된다. 보일러 플레이트인 react-app을 이용해서 패키지가 다 깔려있는 상태로 시작하는 것이다.

week_1 폴더 안에서 jsconfig.json 파일을 하나 만들어서 아래와 같이 작성해서 넣어주면 앞으로 src 폴더 안의 파일들을 import 할 때는 상대경로를 작성해주지 않아도 된다.

// jsconfig.json
{
  "compilerOptions": { "baseUrl": "src" },
  "include": ["src"]
}

1. useState

useState와 같은 hook을 사용하는 가장 근본적인 이유는 무엇일까? 그것은 바로 화면을 렌더링하기 위해서이다.
useState를 사용할 때는 초기값을 설정해주고, 배열을 반환 받는다. 첫 번째 반환받는 인자로 상태에 대한 데이터를, 두 번째 인자로 그 데이터를 바꿔주는 modifier 함수를 준다. 이때 데이터는 초기값으로 설정해준 값을 받는다.

useState를 사용해서 유저의 Id,pw를 입력받고 받은 값을 alert로 띄워서 보여주는 예시를 만들어보겠다.

// App.py
function App() {
  const [data, setData] = useState({ id: "", pw: "" });

  const handleChangeState = (e) => {
    setData({ ...data, [e.target.name]: e.target.value });
  };
  const handleLogin = () => {
    alert(`입력한 아이디 : ${data.id} 입력한 비밀번호 : ${data.pw}`);
    setData({ id: "", pw: "" });
  };
  return (
    <div>
      <div>
        아이디
        <input name="id" type="text" value={data.id} onChange={handleChangeState} />
        비밀번호
        <input name="pw" type="text" value={data.pw} onChange={handleChangeState} />
      </div>
      <button onClick={handleLogin}>로그인하기</button>
    </div>
  );
}

1-1. state를 사용해서 count하기

function App() {
  const [count, setCount] = useState(0);
  const handleIncrease = () => {
    setCount((count) => count + 1);
  };
  const handleDecrease = () => {
    setCount((count) => count - 1);
  };
  return (
    <div>
      <h1>{count}</h1>
      <button onClick={handleIncrease}>+</button>
      <button onClick={handleDecrease}>-</button>
    </div>
  );
}

1-2. CRD 만들어보기

useState를 활용하여 Create, Read, Delete 기능을 구현해보겠다. (연습용이라 일부러 하나의 App.js 파일에 만들어서 가독성이 떨어짐)

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

const UserItem = ({ userItem, onRemove }) => {
  const handleRemove = () => {
    window.confirm(`${userItem.id}번째 정보를 진짜 삭제하시겠습니까?`) && onRemove(userItem.id);
  };
  return (
    <div>
      <div className="UserItem">
        <p>{`${userItem.name}`}</p>
        <p>{`${userItem.age}`}</p>
      </div>
      <button onClick={handleRemove}>삭제하기</button>
    </div>
  );
};

const UserList = ({ userList, onRemove }) => {
  // App의 전체 유저 정보가 담긴 데이터를 가지고 리스트를 만들어줌
  // userList = [{name:"", age:""}, {정보2}..]
  return (
    <div className="UserList">
      {/* userList의 길이만큼 userItem을 만들어야 하니까 map으로 생성 */}
      {userList.map((i) => {
        return <UserItem userItem={i} onRemove={onRemove} key={i.id} />;
      })}
    </div>
  );
};

const UserEditor = ({ onCreate }) => {
  const [users, setUsers] = useState({ name: "", age: "" });
  // 이름과 나이를 입력했을 때
  const handleChangeState = (e) => {
    setUsers({ ...users, [e.target.name]: e.target.value });
  };
  // 추가하기 버튼을 눌렀을 때
  const handleSubmit = () => {
    onCreate(users);
    setUsers({ name: "", age: "" });
    alert("추가 완료!");
  };
  return (
    <div>
      <div>
        <input name="name" type="text" value={users.name} onChange={handleChangeState} />
        <input name="age" type="text" value={users.age} onChange={handleChangeState} />
      </div>
      <button onClick={handleSubmit}>추가하기</button>
    </div>
  );
};

function App() {
  const [data, setData] = useState([]);

  // 유저 key 생성
  const dataId = useRef(0);

  // 유저 생성
  const onCreate = ({ name, age }) => {
    // UserEditor에서 유저의 이름과 나이를 받으면 그 값으로 App의 data에 추가해주기
    const newData = {
      name,
      age,
      id: dataId.current,
    };
    dataId.current++;
    setData([...data, newData]);
  };
  // 유저 삭제
  const onRemove = (id) => {
    const newUsers = data.filter((i) => i.id !== id);
    setData(newUsers);
  };
  return (
    <div>
      <UserEditor onCreate={onCreate} />
      <UserList userList={data} onRemove={onRemove} />
    </div>
  );
}

export default App;

정리

아직은 컴포넌트를 어느 단계에서 분리해야하는지 정확하게 모르겠지만, 일단 기능 별로 구분해서 컴포넌트를 만들고 prop을 이곳저곳에서 사용하는 시행착오를 해보고 CRD 하는 것을 만들어보니 조금은 알겠다
역시 만들어보면서 좀 더 배워야겠다.

0개의 댓글