4 분 소요

To Do.

  1. 폰트 세팅
  2. 레이아웃 세팅
  3. 이미지 에셋 세팅
  4. 공통 컴포넌트 세팅

폰트 세팅

https://fonts.google.com/ 에서 사용

거기서 폰트트 추가해서 @import 부분에서 style 태그를 제외한 나머지를 복사해서 붙혀넣기 한다

레이아웃 세팅

@import url("https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&family=Yeon+Sung&display=swap");
body {
  background-color: #f6f6f6;
  display: flex;
  justify-content: center;
  align-items: center;
  font-family: "Nanum Pen Script";
  min-height: 100vh;
  margin: 0px;
}
@media (min-width: 650px) {
  .App {
    width: 640px;
  }
}

@media (max-width: 650px) {
  .App {
    width: 90vw;
  }
}

#root {
  background: white;
  box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 20px 0px;
}

.App {
  min-height: 100vh;
  padding-left: 20px;
  padding-right: 20px;
}
  • body: 페이지 전체에 해당
  • #root: root 아래에 있는 모든 컴포넌트에 해당
  • .App: App 컴포에만 해당

이미지 에셋 세팅

import "./App.css";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import New from "./pages/New";
import Edit from "./pages/Edit";
import Diary from "./pages/Diary";

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <h2>App.js</h2>

        <img src={process.env.PUBLIC_URL + `/assets/emotion1.png`} />
        <img src={process.env.PUBLIC_URL + `/assets/emotion2.png`} />
        <img src={process.env.PUBLIC_URL + `/assets/emotion3.png`} />
        <img src={process.env.PUBLIC_URL + `/assets/emotion4.png`} />
        <img src={process.env.PUBLIC_URL + `/assets/emotion5.png`} />

        <Routes>
          <Route path="/" element={<Home></Home>}></Route>
          <Route path="/new" element={<New></New>}></Route>
          <Route path="/edit" element={<Edit></Edit>}></Route>
          <Route path="/diary/:id" element={<Diary></Diary>}></Route>
        </Routes>
      </div>
    </BrowserRouter>
  );
}

export default App;

이미지 불러오기

공통 컴포넌트 세팅

공통으로 사용되는 버튼이나 헤더 컴포넌트 세팅하는 작업이다. 해당 버튼은 type=positive, negative, default로 나뉘고, 버튼 위의 text와 onClick 했을 때의 이벤트를 필요로 한다.

step 1. 일단 버튼 컴포 만들고 스타일링

// src > components > MyButton.js
const MyButton = ({ text, type, onClick }) => {
  return (
    <button className={"MyButton"} onClick={onClick}>
      {text}
    </button>
  );
};

export default MyButton;

App.js에 MyButton 컴포넌트 넣어주기

/* App.css */

/* MyButton */
.MyButton {
  cursor: pointer;
  border: none;
  border-radius: 5px;

  padding-top: 10px;
  padding-bottom: 10px;
  padding-left: 20px;
  padding-right: 20px;

  font-size: 18px;
  white-space: nowrap;
  font-family: "Nanum Pen Script";
}

type에 따라 버튼 색깔 다르게 하기

// src > components > MyButton.js
const MyButton = ({ text, type, onClick }) => {
  const btnType = ["positive", "negative"].includes(type) ? type : "default";

  return (
    <button
      className={["MyButton", `MyButton_${type}`].join(" ")}
      onClick={onClick}
    >
      {text}
    </button>
  );
};
MyButton.defaultProps = {
  type: "default",
};
export default MyButton;

type의 이름은 className에 같이 지정해버리는 것이다. 여기서 공통 속성인 MyButton 안에 MyButton_type 을 통해서 디자인은 비슷하지만 색깔을 다르게 지정할 수 있는 것이다.

/* MyButton */
.MyButton {
  cursor: pointer;
  border: none;
  border-radius: 5px;

  padding-top: 10px;
  padding-bottom: 10px;
  padding-left: 20px;
  padding-right: 20px;

  font-size: 18px;
  white-space: nowrap;
  font-family: "Nanum Pen Script";
}
.MyButton_default {
  background: #ececec;
  color: black;
}
.MyButton_positive {
  background: #64c064;
  color: white;
}
.MyButton_negative {
  background: #fd565f;
  color: white;
}

step 2. 헤더 만들기

헤더 컴포넌트를 만들고, 인자로 받을 값들을 지정한다.

const MyHeader = ({ headText, leftChild, rightChild }) => {
  return (
    <header>
      <div className="head_btn_left">{leftChild}</div>
      <div className="head_text">{headText}</div>
      <div className="head_btn_right">{rightChild}</div>
    </header>
  );
};

export default MyHeader;

그런 다음 App 컴포넌트에 넣고 css 스타일링

// src > App.js
<MyHeader
  headText={"App"}
  leftChild={
    <MyButton text={"왼쪽 버튼"} onClick={() => alert("왼쪽 클릭")}></MyButton>
  }
  rightChild={
    <MyButton
      text={"오른쪽 버튼"}
      onClick={() => alert("오른쪽 클릭")}
    ></MyButton>
  }
></MyHeader>
/* src > App.css */
/* Header */
header {
  padding-top: 20px;
  padding-bottom: 20px;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #e2e2e2;
}
header > div {
  display: flex;
}
header .head_text {
  width: 50%;
  font-size: 25px;
  justify-content: center;
}
header .head_btn_left {
  width: 25%;
  justify-content: start;
}
header .head_btn_right {
  width: 25%;
  justify-content: end;
}
header button {
  font-family: "Nanum Pen Script";
}

상태 관리 세팅하기

리액트 기본에서 사용했던 useReducer 훅을 사용한다.

const reducer = (state, action) => {
  let newState = [];
  switch (action.type) {
    case "INIT": {
      return action.data;
    }
    case "CREATE": {
      const newItem = {
        ...action.data,
      };
      newState = [newItem, ...state];
      break;
    }
    case "REMOVE": {
      newState = state.filter((it) => it.id !== action.targetId);
      break;
    }
    case "EDIT": {
      newState = state.map((it) =>
        it.id === action.data.id ? { ...action.data } : it
      );
      break;
    }
    default:
      return state;
  }
  return newState;
};

그리고 App 컴포넌트에 Create, Remove, Edit 에 해당하는 코드를 작성한다.

const [data, dispatch] = useReducer(reducer, []);
const dataId = useRef(0);
// CREATE
const onCreate = (date, content, emotion) => {
  dispatch({
    type: "CREATE",
    data: {
      id: dataId.current,
      date: new Date(date).getTime(),
      content,
      emotion,
    },
  });
  dataId.current += 1;
};
// REMOVE
const onRemove = (targetId) => {
  dispatch({ type: "REMOVE", targetId });
};
// EDIT
const onEdit = (targetId, date, content, emotion) => {
  dispatch({
    type: "EDIT",
    data: {
      id: targetId,
      date: new Date(date).getTime(),
      content,
      emotion,
    },
  });
};

프로젝트 State Context 세팅하기

// src > App.js
export const DiaryStateContext = React.createContext();

을 통해서 내보내줄 컴포넌트 만듬.

// src > App.js
return (
  <DiaryStateContext.Provider value={data}>
    <BrowserRouter>
      <div className="App">
        <Routes>
          <Route path="/" element={<Home></Home>}></Route>
          <Route path="/new" element={<New></New>}></Route>
          <Route path="/edit" element={<Edit></Edit>}></Route>
          <Route path="/diary/:id" element={<Diary></Diary>}></Route>
        </Routes>
      </div>
    </BrowserRouter>
  </DiaryStateContext.Provider>
);

<DiaryStateContext.Provider value={data}> 을 통해서 value 값으로 data를 전달해주어서 Props 드릴링 문제를 해결한다.

프로젝트 Dispatch Context 세팅하기

export const DiaryDispatchContext = React.createContext();
return (
  <DiaryStateContext.Provider value={data}>
    <DiaryDispatchContext.Provider value=>
      <BrowserRouter>
        <div className="App">
          <Routes>
            <Route path="/" element={<Home></Home>}></Route>
            <Route path="/new" element={<New></New>}></Route>
            <Route path="/edit" element={<Edit></Edit>}></Route>
            <Route path="/diary/:id" element={<Diary></Diary>}></Route>
          </Routes>
        </div>
      </BrowserRouter>
    </DiaryDispatchContext.Provider>
  </DiaryStateContext.Provider>
);

<DiaryDispatchContext.Provider value=> 을 이용해 한 번 더 감싸준다.

  • DiaryStateContext: 데이터 state 관련 Context 컴포넌트
  • DiaryDispatchContext: 메소드 관련 Context 컴포넌트

태그:

카테고리:

업데이트:

댓글남기기