리액트

차곡·2022년 3월 27일
0

리액트 시작 전 node.js 설치
https://nodejs.org/ko/

리액트 시작

npx create-react-app ~
cd ~
npm start

npm start를 하면서 엄청난 에러를 만났고
에러 구글 서치하고 몇십 분 동안 계속 찾아봤는데 안돼서
리액트 다시 시작을 했는데 너무 간단하게 돼서 좀 화가 났다

package.json

 "scripts": {
    "start": "react-scripts start", //개발모드 실행
    "build": "react-scripts build", //실제 배포모드
    "test": "react-scripts test", // 테스트
    "eject": "react-scripts eject" //웹페이지, vavel설정 변경시 사용
  },

component

리엑트로 만든 페이지는 컴포넌트들로 구성되어있음
페이지 단위로 html을 작성하는게 아니라
각 부분을 컴포넌트로 만들어서 조립해서 사용
비슷한 부분은 코드를 재사용할 수 있고 유지보수도 한결 쉬워짐

App.js

import './App.css';

function App() {
  return (
    <div className="App"></div>
  );
}

export default App;

의 상태로 시작

함수로 만들어진 컴포넌트 = 함수형 컴포넌트
모든 컴포넌트는 대문자로 시작해야 함

import "./App.css";

function App() {
  const name = "Tom";
  const naver = {
    name: "네이버",
    url: "https://naver.com",
  };
  return (
    <div className="App">
      <h1 style={{ color: "#333", backgroundColor: "green" }}>
        Hello, {name}.<p>{2 + 3}</p>
      </h1>
      <a href={naver.url}>{naver.name}</a>
    </div>
  );
}

export default App;

컴포넌트 만들기

src > component > Hello.js 파일 생성

export default function Hello() {
  return <p>Hello</p>;
}

 const Hello = () => {
     <p>Hello</p>;
 };
export default function Hello() {
    return <p>Hello</p>;
}

App.js

import "./App.css";
import Hello from "./component(.js)/Hello";
(.js 빼고 적어도 됨)

function App() {
  return (
    <div className="App">
      <Hello />
    </div>
  );
}

export default App;

welcome.js

export default function Welcome() {
    return <h2>Welcome</h2>;
}

world.js

export default function World() {
    return <h3>World!</h3>;
}

css
css 모듈 사용
(기존 Hello.css를 => Hello.module.css 로 변경)

import World from "./World";
import styles from "./Hello.module.css";

export default function Hello() {
  return (
    <div>
      <h1>Hello</h1>
      <World />
      <div className={styles.box}>Hello</div> 
    </div>
  );
}

이벤트

export default function Hello(){
	function showName(){
    	console.log("cgok");
    }
    
    function(e){
    	console.log(e.target.value)
    }
    
    return(
    	<>
        <button onClick={showName}>show name</button>
        <button onClick={
        	()=>{
            console.log(age)
            }
        }>show name</button>
        
        <input type="text" onChange={showText}/>
        </>
    )
}

state

export default function Hello() {
  let name = "cgok";

  function changeName() {
    name = name === "cgok" ? "chgk" : "cggo";
    console.log(name);
    document.getElementById("name").innerText = name;
  }

  return (
    <div>
      <h1>state</h1>
      <h2 id="name">{name}</h2>
      <button onClick={changeName}>Change</button>
    </div>
  );
}

props

App.js

import "./App.css";
import Hello from "./component/Hello";

function App(){
	return (
    	<div className ="App">
        	<h3>props : properties</h3>
            <Hello age={10}/>
            <Hello age={20}/>
            <Hello age={30}/>
        </div>
    );
}

export default App;

Hello.js

import { useState } from "react"; 

export default function Hello({ age }) { 
    const  [name, setName] = useState('Mike'); 
    const msg = age > 19 ? "성인 입니다. " : "미성년자 입니다.";
    
    function changeName() {
    	const newName = name === "Mike" ? "Jane" : "Mike";
        setName(newName)
    }
    
    return (
    	<>
			<h2 id="name"> {name}({props.age}) : {msg} </h2> /
			<button onClick = {changeNAme}>Change</button>
        </>
    )
    
}

dummy data

App.js

import "./App.css";
import DayList from "./component.js/DayList";
import Header from "./component.js/Header";
import Day from "./component.js/Day";

function App() {
  return (
    <div className="App">
      <Header />
      <DayList />
      <Day />
    </div>
  );
}

export default App;

Day.js

import dummy from "../db/data.json";

export default function Day() {
  //dummy.words
  const day = 2;
  const wordList = dummy.words.filter((word) => word.day === day);
  console.log(wordList);

  return (
    <>
      <table>
        <tbody>
          {wordList.map((word) => (
            <tr key={word.id}>
              <td>{word.eng}</td>
              <td>{word.kor}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </>
  );
}

router 구현
npm install react-router-dom

import "./App.css";
import Day from "./component/Day";
import DayList from "./component/DayList";
import Header from "./component/Header";
import { BrowserRouter, Route, Routes } from "react-router-dom"; 

function App() {
  return (
    <BrowserRouter> 
      <div className="App">
        <Header />
        <Routes>
          <Route path="/" element={<DayList />} />
          <Route path="/day" element={<Day />} />
        </Routes>
      </div>
    </BrowserRouter>
  );
}

export default App;
//DayList.js
import { Link } from "react-router-dom";
import dummy from "../db/data.json";

export default function DayList() {
  return (
    <ul className="list_day">
      {dummy.days.map((day) => (
        <li key={day.id}>
          <Link to={`/day/${day.day}`}>Day {day.day}</Link>
        </li>
      ))}
    </ul>
  );
}

json-server
npm install -g json-server
json-server --watch ./src/db/data.json --port 3001

word.js

import { useState } from "react";

export default function Word({ word }) {
  const [isShow, setIsShow] = useState(false);
  const [isDone, setIsDone] = useState(word.isDone);

  function toggleShow() {
    setIsShow(!isShow);
  }

  function toggleDone() {
    setIsDone(!isDone);
  }

  return (
    <tr className={isDone ? "off" : ""}>
      <td>
        <input type="checkbox" checked={word.isDone} onChange={toggleDone} />
      </td>
      <td>{word.eng}</td>
      <td>{isShow && word.kor}</td>
      <td>
        <button onClick={toggleShow}>뜻 {isShow ? "숨기기" : "보기"}</button>
        <button className="btn_del">삭제</button>
      </td>
    </tr>
  );
}

Day.js

import dummy from "../db/data.json";
import { useParams } from "react-router-dom";
import Word from "./Word ";

export default function Day() {
  const a = useParams();
  const day = a.day;
  const wordList = dummy.words.filter((word) => word.day === Number(day));

  return (
    <>
      <h2>Day {day}</h2>
      <table>
        <tbody>
          {wordList.map((word) => (
            <Word word={word} key={word.id} />
          ))}
        </tbody>
      </table>
    </>
  );
}

App.js

import "./App.css";
import DayList from "./component.js/DayList";
import Header from "./component.js/Header";
import Day from "./component.js/Day";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import EmptyPage from "./component.js/EmptyPage";

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Header />
        <Routes>
          <Route path="/" element={<DayList />} />
          <Route path="/day/:day" element={<Day />} />
          <Route path="*" element={<EmptyPage />} />
        </Routes>
      </div>
    </BrowserRouter>
  );
}

export default App;

useEffect, fetch()

import { useEffect, useState } from "react";
import { Link } from "react-router-dom";

export default function DayList() {
  const [days, setDays] = useState([]);

  useEffect(() => {
    fetch("http://localhost:3001/days")
      .then((res) => {
        return res.json();
      })
      .then((data) => {
        setDays(data);
      });
  }, []);

  return (
    <>
      <ul className="list_day">
        {days.map((day) => (
          <li key={day.id}>
            <Link to={`/day/${day.day}`}>Day {day.day}</Link>
          </li>
        ))}
      </ul>
    </>
  );
}

커스텀 훅

DayList.js

import { Link } from "react-router-dom";
import useFetch from "../hooks/useFetch";

export default function DayList() {
  const days = useFetch("http://localhost:3001/days");

  return (
    <ul className="list_day">
      {days.map((day) => (
        <li key={day.id}>
          <Link to={`/day/${day.day}`}>Day {day.day}</Link>
        </li>
      ))}
    </ul>
  );
}

Day.js

import { useParams } from "react-router-dom";
import useFetch from "../hooks/useFetch";
import Word from "./Word ";

export default function Day() {
  const { day } = useParams();

  const words = useFetch(`http://localhost:3001/words?day=${day}`);

  return (
    <>
      <h2>Day {day}</h2>
      <table>
        <tbody>
          {words.map((word) => (
            <Word word={word} key={word.id} />
          ))}
        </tbody>
      </table>
    </>
  );
}

delete

function del() { 
    if (window.confirm("삭제 하시겠습니까?")) {
      fetch(`http://localhost:3001/words/${word.id}`, {
        method: "DELETE",
      }).then((res) => {
        if (res.ok) {
          setWord({ id: 0 });
        }
      });
    }
  }

  if (word.id === 0) {
    return null;
  }

  return (
    <tr className={isDone ? "off" : ""}>
      <td>
        <input type="checkbox" checked={isDone} onChange={toggleDone} />
      </td>
      <td>{word.eng}</td>
      <td>{isShow && word.kor}</td>
      <td>
        <button onClick={toggleShow}>뜻 {isShow ? "숨기기" : "보기"}</button>
        <button onClick={del} className="btn_del">
          삭제
        </button>
      </td>
    </tr>
  );
}

로딩화면

DayList

import { Link } from "react-router-dom";
import useFetch from "../hooks/useFetch";

export default function DayList() {
  const days = useFetch("http://localhost:3001/days");

  if (days.length === 0) {
    return <span>Loading...</span>;
  }

  return (
    <ul className="list_day">
      {days.map((day) => (
        <li key={day.id}>
          <Link to={`/day/${day.day}`}>Day {day.day}</Link>
        </li>
      ))}
    </ul>
  );
}

Day.js

import { useParams } from "react-router-dom";
import useFetch from "../hooks/useFetch";
import Word from "./Word ";

export default function Day() {
  const { day } = useParams();
  const words = useFetch(`http://localhost:3001/words?day=${day}`);

  return (
    <>
      <h2>Day {day}</h2>
      {words.length === 0 && <span>Loading...</span>}
      <table>
        <tbody>
          {words.map((word) => (
            <Word word={word} key={word.id} />
          ))}
        </tbody>
      </table>
    </>
  );
}
profile
기획과 개발을 배워요.

0개의 댓글

관련 채용 정보