728x90

프로젝트 초기 세팅을 정리해놓지 않으니 매번 시작할 때마다 까먹어서 이 참에 정리를 해놓으려고 한다.
순서는 상관이 없고, 이 세팅이 정답도 아니다.
개인별로, 팀별로, 회사별로 다 다를테니 어떤 흐름인지만 확인하면 될 것 같다.

 

Backend 초기 세팅은 여기로

1. CRA(create react app) 설치

일단 node.js가 설치되어 있다는 가정하에 시작한다.

npx create-react-app test-proejct

위 명령어를 실행한 폴더 하위에 'test-project'이라는 폴더가 생기면 CRA 설치 완료.
해당 폴더를 vsc로 열면 아래와 같은 폴더 구조를 갖게 된다.

vsc에서 터미널(단축키: cmd + j)을 열어 npm start 명령어를 실행하면 아래와 같이 정상적으로 실행이 되는 것을 확인할 수 있다.

2. 필요한 패키지 설치

패키지는 개인, 팀 별로 천차 만별일테니 참고만.

패키지 설치시 package.json 파일에 해당 패키지가 추가가 되는지 꼭 확인한다.
만약 추가가 되어 있지 않으면 해당 프로젝트를 다른 사람이 clone 받았을 때 패키지를 설치할 수가 없다.

 

<패키지 설치 옵션 간단 설명>
--save : dependencies에 추가됨(npm5 이상부터 생략 가능)(dependencies : 실제 애플리케이션 운용에 필요한 패키지)
--save-dev(또는 -D) : devDependencies에 추가됨(devDependencies : 개발에 필요한 패키지)


a. devDependencies
1. npm i eslint-config-prettier --save-dev(eslint-config-prettier : prettier와 충돌할 설정들을 비활성화)
2. npm i eslint-plugin-prettier --save-dev(eslint-plugin-prettier : eslint에 prettier의 포매팅 기능을 추가)
3. npm i prettier --save-dev --save-exact(--save-exact : 버전이 달라지면서 생길 스타일 변화를 막기 위함)
b. dependencies
1. npm i react-router-dom --save(react-router-dom : router 사용)
2. npm i styled-components --save(styled-components : javascript에서 css 사용이 가능한 스타일링 프레임워크)
3. npm i styled-reset --save(styled-reset : css 설정 초기화)

최종적으로 설치된 패키지(package.json)

3.  환경 설정

환경 설정 역시 개인, 팀 별로 다를테니 참고만.


a. .eslintrc 파일 생성

{ "extends": ["react-app", "plugin:prettier/recommended"] }

b. .prettierrc 파일 생성

{
  "printWidth": 80,
  "tabWidth": 2,
  "singleQuote": true,
  "trailingComma": "all",
  "bracketSpacing": true,
  "semi": true,
  "arrowParens": "avoid",
  "endOfLine": "lf" 
}

c. .gitignore 설정
.eslintcache 추가

d. .env 설정
.env는 환경변수 파일로 key = value 형태로서 변수로 설정된 key에 해당하는 값을 process.evn.key 형태로 사용이 가능하다.

REACT_APP_SERVER_HOST="http://localhost:8000"
REACT_APP_CLIENT_HOST="http://localhost:3000"

만약 위와 같이 .env에 서버 주소를 지정하면 fetch 함수를 사용해서 백엔드와 통신을 할 때 아래와 같이 사용이 가능하다.

fetch(`${process.env.REACT_APP_SERVER_HOST}/user/signin`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  mode: 'cors',
  body: JSON.stringify({
    email: emailValue,
    password: pwValue,
  }),
})

4. public 폴더 및 src 폴더 수정

이부분도 개인, 팀 별로 다를 테니 참고만.


a. public 폴더(아래 사진)
- images 폴더 생성
- 불필요한 파일 삭제
- index.html에서 불필요한 부분 삭제 및 추가

b. src 폴더(변동이 많기 때문에 자세한 코드는 아래 github에서 확인)
- 불필요한 파일 삭제
- components, pages, styles 폴더 생성
- Routes.js 파일 생성(react-router-dom 패키지를 사용할 경우)
- config.js 파일 생성(API를 일괄적으로 관리해주기 위한 용도)
- GlobalStyle.js, Theme.js 파일 생성(styled-components 패키지를 사용할 경우)

5. 최종 결과물

위와 같이 초기 설정을 해서 나온 결과물은 아래 그림과 같다. 코드는 아래 gitghub에서 확인 가능!

https://github.com/quark4904/test-project-front

틀린 부분이나 부족한 부분이 있으면 댓글 부탁 드립니다!


반응형

'Programming > React' 카테고리의 다른 글

[React.js]Link로 props 전달하기  (0) 2022.01.13
[React.js]React.memo() 알아보기  (0) 2021.12.26
[React]export와 export default의 차이  (0) 2021.11.30
728x90

내가 어떤 페이지에 특정 데이터를 전달하고 싶은 경우, react에서는 일반적으로 부모자식 관계로 설정해서 props를 전달하게 된다. 

하지만 만약 부모자식 관계가 아닌데도 props를 전달해야 할 필요가 있을 경우에는 어떻게 데이터를 전달할까..

결론은 Link 컴포넌트를 이용하면 된다. 

 

아래와 같은 경우를 생각해보자.

Router.js가 아래와 같이 구성되어 있고, 

// Router.js
import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import Main from "./pages/Main";

function Router() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/main" element={<Main />} />
      </Routes>
    </BrowserRouter>
  );
}

export default Router;

Home.js는 아래와 같이 로그인/회원가입 버튼을 누르면 /main 경로로 할당된 Main.js 컴포넌트로 가게끔 되어있다. 

// Home.js
import { Link } from "react-router-dom";

function Home() {
  return (
    <div>
      <Link to="/main">
        <button>로그인</button>
      </Link>
      <Link to="/main">
        <button>회원가입</button>
      </Link>
    </div>
  );
}

export default Home;

그런데 Main.js안에는 아래 사진 및 코드와 같이 useState를 사용해서 초기값을 true로 설정을 해줘서 Main.js가 렌더링 되면 무조건 SignIn.js가 렌더링 되게 되어있다.

Home.js에서 로그인 버튼을 누르면 로그인으로 페이지가 열리고, 회원가입 버튼을 누르면 회원가입 페이지가 열리게 하고 싶은데, 

만약 Home.js와 Main.js가 같은 페이지였다면, 부모자식 간에 props를 전달하는 방법으로 손쉽게 해결이 될 것 같다. 그런데 이 경우는 아예 다른 페이지이기 때문에 기존 방법으로는 props를 넘겨줄 수가 없다. 

// Main.js
import { useState } from "react";
import "./Main.scss";
import SignIn from "./SignIn";
import SignUp from "./SignUp";

function Main() {
  const [isLogin, setIsLogin] = useState(true);

  const onClickSignIn = (event) => {
    setIsLogin(true);
  };
  const onClickSignUp = (event) => {
    setIsLogin(false);
  };
  
  return (
    <div className="loginContainer">
      <div className="btns">
        <button className="btn" onClick={onClickSignIn}>
          로그인
        </button>
        <button className="btn" onClick={onClickSignUp}>
          회원가입
        </button>
      </div>
      {isLogin ? <SignIn /> : <SignUp />}
    </div>
  );
}

export default Main;

해결방법은 Main.js 파일의 isLogin state 초기값인 true를 Home.js의 회원가입 버튼을 눌렀을 땐, false로 변경되게끔 수정해주면 된다. 

즉, Home.js의 회원가입 버튼에 state false값을 실어보내주면 된다.

// 수정된 Home.js
import { Link } from "react-router-dom";

function Home() {
  return (
    <div>
      <Link to="/main">
        <button>로그인</button>
      </Link>
      <Link to="/main" state={{ signUp: false }}> // 수정된 부분(객체로 값을 전달해준다.)
        <button>회원가입</button>
      </Link>
    </div>
  );
}

export default Home;
// 수정된 Main.js
import { useState } from "react";
import { useLocation } from "react-router-dom"; // 추가된 부분
import "./Main.scss";
import SignIn from "./SignIn";
import SignUp from "./SignUp";

function Main() {
  const location = useLocation(); // 추가된 부분
  const signUp = location.state?.signUp; // 추가된 부분

  const [isLogin, setIsLogin] = useState(signUp === false ? false : true); // 수정된 부분

  const onClickSignIn = (event) => {
    setIsLogin(true);
  };
  const onClickSignUp = (event) => {
    setIsLogin(false);
  };

  return (
    <div className="loginContainer">
      <div className="btns">
        <button className="btn" onClick={onClickSignIn}>
          로그인
        </button>
        <button className="btn" onClick={onClickSignUp}>
          회원가입
        </button>
      </div>
      {isLogin ? <SignIn /> : <SignUp />}
    </div>
  );
}

export default Main;

 

결과는 아래와 같다. 

반응형

'Programming > React' 카테고리의 다른 글

[React]Frontend 초기 세팅  (0) 2022.02.04
[React.js]React.memo() 알아보기  (0) 2021.12.26
[React]export와 export default의 차이  (0) 2021.11.30
728x90

자식 컴포넌트 두개가 있는데, 한쪽 자식에게 전달하는 props에만 변경이 생긴경우,

특별한 조건을 주지 않는한 부모는 그 둘 모두를 렌더링(rendering) 하게 된다. 

 

그런데 만약 자식 컴포넌트가 1000개 라면 자식 하나의 변경만으로도 나머지 자식들 모두가 새롭게 렌더링되야하므로 시간이 지연이 발생하게 될 것이다. 

 

이때 유용하게 사용되는 메소드가 React.memo()다.

 

아래와 같이 React.memo()를 사용하면 처음에는 두 컴포넌트가 모두 렌더링 되고,

이후에는 변경된 자식 컴포넌트만 렌더링이 된다.

function Btn({ text, changeValue }) {
  console.log(text, "was chaneged"); 
  
  // 처음 렌더링 됐을 때,
  // Save Changes was chaneged
  // Continue was chaneged
  
  // onClick 이벤트 적용 후 렌더링 됐을 때,
  // Revert Changes was chaneged
  
  return (
    <button
      style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "10px 20px",
        border: 0,
        borderRadius: 10,
      }}
      onClick={changeValue}
    >
      {text}
    </button>
  );
}

const MemorizedBtn = React.memo(Btn);

function App() {
  const [value, setValue] = React.useState("Save Changes");
  const changeValue = (event) => {
    setValue("Revert Changes");
  };
  return (
    <div>
      <MemorizedBtn text={value} changeValue={changeValue} />
      <MemorizedBtn text="Continue" />
    </div>
  );
}
반응형

'Programming > React' 카테고리의 다른 글

[React]Frontend 초기 세팅  (0) 2022.02.04
[React.js]Link로 props 전달하기  (0) 2022.01.13
[React]export와 export default의 차이  (0) 2021.11.30
728x90

export default

1. 일반적으로 해당 모듈엔 하나의 개체(변수, 클래스, 함수 등)만 있다는 의미로 받아들여진다. 

2. 따라서 해당 모듈의 전체 개체를 export 한다는 의미를 갖는다.

3. 원하는 이름으로 import가 가능하다.(ex. import ThisIsSample from "경로")

// Data.js

function Data() {
  return <h1>Hello, React!</h1>;
}

export default Data;


// DataChild.js

import Data from "./Data"

 

export

1. 복수의 개체가 있는 라이브러리 형태의 모듈에서 가져오기 할 때 사용된다.

2. 특정 개체만 가져오는게 가능하다. 

3. 원하는 이름으로 import가 불가능하다.

// Robot.js

function Robot() {
  return <h1>Hello, React!</h1>;
}

function Robot2() {
  return <h1>Who are you??</h1>;
}

export Robot2;


// RobotChild.js

import { Robot2 } from "./Robot.js"
반응형

'Programming > React' 카테고리의 다른 글

[React]Frontend 초기 세팅  (0) 2022.02.04
[React.js]Link로 props 전달하기  (0) 2022.01.13
[React.js]React.memo() 알아보기  (0) 2021.12.26

+ Recent posts