Skip to content

Instantly share code, notes, and snippets.

@egoing
Last active February 26, 2021 05:49
Show Gist options
  • Save egoing/3fd1e10d13b4f4bfcf269debaff466ea to your computer and use it in GitHub Desktop.
Save egoing/3fd1e10d13b4f4bfcf269debaff466ea to your computer and use it in GitHub Desktop.
React tutorial

step0

목표

리액트의 개발환경을 구축하고 싶다.

힌트

  1. nodejs 설치
  2. npm i create-react-app
  3. create-react-app myapp
  4. cd myapp
  5. npm start

결과

step1

목표

아래의 코드를 리액트화하고 싶다.

<header>
    <h1>WEB</h1>
</header>
<nav>
    <ul>
        <li>
        <a href="/1">html</a>
        </li>
        <li>
        <a href="/2">css</a>
        </li>
        <li>
        <a href="/3">javascript</a>
        </li>
    </ul>
</nav>
<article>
    <h2>Welcome</h2>
    Hello, WEB!
</article>

결과

step2

목표

header, nav, article 태그가 너무 복잡합니다. 이들을 컴포넌트화하고 싶다.

힌트

각 태그를 Header, Nav, Article 라는 이름의 컴포넌트로 만들어서 단순화 해보세요.

function Header() {
  //todo
}
function Nav() {
  //todo
}
function Article() {
  //todo
}
export default function App() {
  return (
    <div>
      <Header />
      <Nav />
      <Article />
    </div>
  );
}

결과

step 3

목표

컴포넌트가 너무 경직 되어 있습니다. HTML 태그 처럼 속성을 통해서 컴포넌트를 커스터마이징 하고 싶습니다.

힌트

아래와 같은 인터페이스를 가지고 있는 컴포넌트를 만들어보세요.

function Nav(props) {
  //todo
}
function Article(props) {
  //todo
}
export default function App() {
  return (
    <div>
      <Header />
      <Nav
        data={[
          { id: 1, title: "html", description: "html is..." },
          { id: 2, title: "css", description: "css is..." },
          { id: 3, title: "js", description: "js is..." }
        ]}
      />
      <Article title="제목" description="본문" />
    </div>
  );
}

5.1 step3 - props - 단순데이터의 결과

5.2 step3 - props - 목록 데이터의 결과

step 4

목표

컴포넌트에 이벤트 기능을 부여하고 싶습니다.

알아야 할 것

  1. 컴포넌트에 이벤트 기능을 부여하는 것
  2. 스테이트를 통해서 내부의 상태를 변경하는 것

힌트

function Header(props) {
  //todo
}
function Nav(props) {
  //todo
}
export default function App() {
  var [mode, setMode] = useState("WELCOME");
  var [selectedId, setSelectedId] = useState(null);
  var topics = [
    { id: 1, title: "html", description: "html is..." },
    { id: 2, title: "css", description: "css is..." },
    { id: 3, title: "js", description: "js is..." }
  ];
  var article = null;
  if (mode === "WELCOME") {
    // todo
  } else if (mode === "READ") {
    // todo
  }
  return (
    <div>
      <Header
        onChangeMode={function() {
          //todo
        }}
      />
      <Nav
        data={topics}
        onChangeMode={function(topic_id) {
          //todo
        }}
      />
      {article}
    </div>
  );
}

7-1 step4 - 이벤트 구현의 결과

7-2 step4 - 이벤트 정보 받기의 결과

7-3 step4 - state의 결과

7-4 step4 - 동적으로 컴포넌트의 값 대입하기

step 5

목표

글생성 기능을 추가하고 싶습니다.

알아야 할 것

  1. 데이터를 변경할 때는 불변성을 유지하도록 주의 합니다.
    1. 원시 데이터 타입은 그냥 변경하면 됩니다.배열과 객체는 원본을 복제한 후에 변경하면 됩니다. 실험실 : https://stackblitz.com/edit/react-state-compare?file=src/App.js
    2. 차이는 다음 영상을 참고해주세요. https://youtu.be/fDJG4CjbB3A?t=215 참고 : https://gist.github.com/aluksidadi/10aa07c6f007efc587f793212548ad51
  2. immutable.js
  3. immutable 과 관련된 이슈는 다음 영상을 참고하세요. https://opentutorials.org/module/4075
  4. immutable.js 와 같은 라이브러리를 이용하는 것을 추천합니다.
  5. 기존 js 문법의 문제점과 immutable.js를 사용하는 이유 : https://docs.google.com/spreadsheets/d/1tn5YI9wDZieZOwJHCaT_cQuixw64tr_iv3Pv6AqdfI8/edit#gid=0

힌트

function Create(props) {
  return (
    <article>
      <h1>Create</h1>
      <form
        action="topics"
        method="post"
        onSubmit={function(e) {
          //todo
        }}
      >
        <p>
          <input type="text" name="title" placeholder="title" />
        </p>
        <p>
          <textarea name="description" placeholder="description" />
        </p>
        <p>
          <input type="submit" />
        </p>
      </form>
    </article>
  );
}
function Control(props) {
  return ( 
    <ul>
      <li>
        <a href="/topics/create" onClick={function(e){
            //todo
        }}>create</a>
      </li>
    </ul>
  );
}
export default function App() {   
  //...
  // todo
  } else if (mode === "CREATE") {
    article = (
      <Create
        onCreate={function(data) {
          //todo
        }}
      />
    );
  }
  return (
    <div>
      //...
      <Control
        onChangeMode={function(mode) {
          //todo
        }}
      />
    </div>
  );
}

8-1 step5 - Create 실행 UI 작업의 결과

8-2 step5 - Create 입력 UI 작업의 결과

8-3 step5 - state가 객체일 때의 변경작업의 결과

8-4 step5 - state를 사용하는 이유의 결과

step 6

목표

수정 기능을 추가하고 싶습니다.

알아야 할 것

  • 폼을 수정할 때는 onChange 이벤트를 통해서 state 값을 수정하고, 수정된 state값이 value에 반영될 수 있도록 처리해야 합니다.

힌트

function Control(props){
  //...
  <li><a href="/topics/update" onClick={function(e){
      e.preventDefault();
      //todo
      
function Update(props){
    //todo

function App() {
  //...
  } else if(mode === 'UPDATE'){
    //todo

결과

step 7

목표

삭제를 구현하고 싶습니다.

힌트

<Control
    onChangeMode={function(mode) {
      if (mode === "DELETE") {
        // todo 
      }
    }}
/>

결과

step 8

목표

코드가 너무 많아졌습니다. 코드를 파일로 분리해서 정리 정돈하고 싶습니다.

알아야 할 것

export, import
https://stackblitz.com/edit/react-exim?file=src/App.js

MyModule.js

// 외부에 노출을 원하지 않는 함수
function privateFunc() {
  return "private";
}
// privateFunc를 이용해서 외부에서 사용되도록 고안된 함수
function publicFunc() {
  return privateFunc() + " + " + "public";
}
// 외부에서 사용할 수 있도록 export 한다.
export { publicFunc };
// 외부에서 renamedFunc로 사용하도록 한다.
export { publicFunc as renamedFunc };
// var, const, let도 가능하다.
export var publicVar = "public var";
function defaultFunc() {
  return "default";
}
export default defaultFunc;

App.js
import { publicFunc } from "./MyModule";
console.log(publicFunc());
import { renamedFunc } from "./MyModule";
console.log(renamedFunc());
import { publicVar } from "./MyModule";
console.log(publicVar);
import my from "./MyModule";
console.log(my());

힌트

아래와 같이 컴포넌트를 파일로 분리해주세요.

import Header from './components/Header';
import Nav from './components/Nav';
import Control from './components/Control';
import Create from './components/Create';
import Update from './components/Update';
import Article from './components/Article';

결과

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment