2020.코딩일지

[React]코딩앙마-voca-(Read - GET)useEffect(),API연결 본문

JS & React

[React]코딩앙마-voca-(Read - GET)useEffect(),API연결

개발하는라푼젤 2022. 7. 30. 10:20
728x90

index.js에서 <React.StrictMode> 가 정의되어있으면 api call을 두번씩

 

1️⃣ React App설치(작업폴더simpleroute가 자동생성됨)

npx모듈은 기존node.js가 설치되어있어야(1)`node-v`로 확인가능, (2)`npx`로 사용가능한지 확인

`npx create-react-app <simpleroute>` <프로젝트명>꺽쇠생략

해당폴더에 들어가서 `npm start`

 

2️⃣`npm install react-router-dom`

 


component하단 파일의 기본양식

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

export default function DayList() {
    
    return (
    <>
        {/*여기에작성*/}
    </>
    );
}

<div className=""> </div>


map 사용법


App.js에서 루트분기하기.

•Routes사용법

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Detail from "./routes/Detail";
import Home from "./routes/Home";

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/movie/:recId" element={<Detail />} />
        {/* :id는 변수이름일 뿐이다 */}
      </Routes>
    </Router>
  );
}
export default App;

•Switch사용법

더보기
import { BrowserRouter, Route, Switch } from "react-router-dom";

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Header /> {/* 늘나와야하니까 그 아래부터 Switch로 감싸기 */}
        <Switch>
          <Route exact path="/">
            <DayList />
          </Route>
          <Route path="/day">
            <Day />
          </Route>
          <Route> {/* path 없이 컴포넌트를넣어주면 '위의 모든상황이 만족이안되었을때!만 작동'..🤔Switch에서만 가능한것같다. */}
            <EmptyPage />
          </Route>
        </Switch>
      </div>
    </BrowserRouter>
  );
}

링크걸기(페이지이동) <a>태그 대신 <Link to>

import { Link } from "react-router-dom";
//예시1 - 간단 링크연결
<Link to="/">Home</Link>

//예시2 - h1태그 '토익영단어(고급)'글자 누르면 페이지이동(링크연결)
<h1>
    <Link to="/">토익 영단어 (고급)</Link>
</h1>
      

//예시3 - 맵안에 링크연결
<ul className="list_day">
      <li>
        {dummy.days.map((el) => (
          <li key={el.id}>
            <Link to="/day">Day {el.day}</Link>
          </li>
        ))}
      </li>
    </ul>

 

//📒App.js의 url주소 뒷부분을 🧚‍♀️변수로:day만들어 보내기
<Route path="/day/:day" element={<Day />} />

//📒해당 component의 js파일 상단에 선언해서 🧚‍♀️변수받아오기
import { useParams } from "react-router-dom";
//App.js의 url에 있는 :day변수를 받아오려면 useParams()가 필요.
    const a = useParams(); //❌
    const day = a.day;    //❌
//같은의미. 한줄로!!!!
    const day = useParms().day;  //❌
//아니근데 이게더 멋있잖아?✅
    const { day } = useParams(); //여기의 day는 문자로 들어오기때문에
//(추가설명)맨끝에 Number화 시켜서 비교하게끔 만들어줘야함(이번 db.json의 el.day는 Number타입)
    const wordList = dummy.words.filter((el) => el.day === Number(day));

props전달

더보기
//📒부모파일에서 
//같은함수내
const { day } = useParams();
const wordList = dummy.words.filter((el) => el.day === Number(day));
//리턴아래
<table>
    <tboy>
       {wordList.map((el) => (
          <Word el={el} key={el.ld} /> // 🧚‍♀️props전달배송은 이렇게한다. 변수명={내용물}
        ))}
    </tboy>
</table>

//📒자식파일에서는 변수명 el로 props를 받았고
export default function Word({ el }) {
  return (
    <tr>
      <td>
        <input type="checkbox" />
      </td>
      <td>{el.eng}</td>
      <td>{el.kor}</td>
      <td>
        <button>뜻보기</button>
        <button class="btn_del">삭제</button>
      </td>
    </tr>
  );
}

useState활용 : button에 onClick사용(글씨가 보였다안보였다)

더보기
import { useState } from "react";

export default function Word({ el }) {
  const [isShow, setIsShow] = useState(false); //1️⃣

  //3️⃣반대로뒤집어주는 실행함수
  function toggleShow() {
    setIsShow(!isShow);
  }

  return (
    <tr>
      <td>
        <input type="checkbox" />
      </td>
      <td>{el.eng}</td>
      <td>{isShow && el.kor}</td> {/* 2️⃣트루일때만보인다 */}
      <td>
        <button onClick={toggleShow}>뜻{isShow ? "숨기기" : "보이기"}</button> {/* 4️⃣실행함수를 onClick걸어주기 */}
        <button className="btn_del">삭제</button>
      </td>
    </tr>
  );
}

 

useState활용 : checkbox에 checked, onChange사용 (체크하면 css적용되게)

더보기
import { useState } from "react";

export default function Word({ el }) {
  const [isShow, setIsShow] = useState(false);
  const [isDone, setIsDone] = useState(el.isDone); //체크박스의 기능넣기3️⃣

  function toggleShow() {
    setIsShow(!isShow);
  }
  //체크박스의 기능넣기4️⃣
  function toggleDone() {
    setIsDone(!isDone);
  }

  return (
    <tr className={isDone ? "off" : ""}>
      {/* 체크박스의 기능넣기2️⃣ 클래스네임넣어서 css.off적용 */}
      <td>
        <input type="checkbox" checked={isDone} onChange={toggleDone} />
        {/* 체크박스의 기능넣기1️⃣ checked, onChange 추가 */}
      </td>
      <td>{el.eng}</td>
      <td>{isShow && el.kor}</td> {/* 2️트루일때만보인다 */}
      <td>
        <button onClick={toggleShow}>뜻 {isShow ? "숨기기" : "보이기"}</button>{" "}
        {/* 실행함수를 onClick걸어주기 */}
        <button className="btn_del">삭제</button>
      </td>
    </tr>
  );
}

 


갱신하고나면, db/data.json의 inDone값이 바뀌진않으니 다시 처음상태로 돌아감또륵...(내가 외운단어들이 다시 부활하는 불상사가)

3️⃣ 그래서 🔮Json-server, REST-API가 필요한거시다!!!

`npm install -g json-server`

`json-server --watch ./src/db/data.json --port 3001` 3000번에는 우리 서버가 돌고있으니깐 3001로 지정해준다.

REST API란, uri주소와 메소드로 CRUD를 요청하는것이다.
http://localhost:3001/words words 전체출력  
http://localhost:3001/words/3 words중에서 id가 3인것만 출력  
http://localhost:3001/words?day=3 words중에서 day가 3인것만 출력  
REST API
Create : POST
Read : GET
Update : PUT
Delete : DELETE 
   

dayList.js에서 쓰던 dummy를 지우고 days라는 state를 만들자.

빈배열로 시작해서 API에서 리스트를 가져와서 연결하는 방법으로 ~

//상단에추가하고 더미삭제
import { useEffect, useState } from "react";

//function안에
const [days, setDays] = useState([]);

useEffect에 🔮server연결하기

useEffect(function[,arr]) `useEffect(() => {},[])`

  • 함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 경우 해당 함수는 Side Effect가 있다
    (출처)

::3가지 타입:: 가벼운함수면몰라도 무거운함수가 계속매번동작하는건 불필요

useEffect(() => {
    console.log("나 useEffect는 DOM구현끝나고도 위에 액션이끝나고도 매번 동작해 매번!")
  });
useEffect(() => {
    console.log("지켜보는곳이 바뀌어야 작동합니다.")
  }, [너를지켜보겠다]); //의존성배열이라고합니다🙂
useEffect(() => {
    console.log("최초1번말고는 더이상지켜보지않겠어!관심끌게.")
  }, []);//최초1회만작동

➣렌더링 완료되고 최초1회만 API호출을 하고싶다면? 의존성배열을 [] 빈배열로 만들면 된다.

const [days, setDays] = useState([]);
  useEffect(() => {
    fetch("http://localhost:3001/days")
      .then((res) => {
        return res.json(); //res는 응답일뿐 실제 제이쓴이아니여서, json()해준것임
      })
      .then((data) => {
        setDays(data); //useState의 갱신함수setDays로전달
      });
  }, []);


비슷하게 중복되는 로직은 못참지!

Custom Hook만들기 (

src/hooks/ 디렉토리생성. 그 아래 useFetch.js를 생성한다.

Custom Hook (useFetch.js)

useFetch.js코드는 여기에

더보기

useFetch.js

import { useEffect, useState } from "react";

export default function useFetch(url) {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch(url)
      .then((res) => {
        return res.json();
      })
      .then((data) => {
        setData(data);
      });
  }, [url]);
  return data;
}

📒DayList.js에 `useFetch("http://localhost:3001/days");`이거 한줄이면 끝남! 오호호

그런데 아래 state적용시켜줘야하니까 변수days에 넣어줘야죠 `const days = useFetch("http://localhost:3001/days");`

최상단에 `import useFetch from "../hooks/useFetch";` 잊지말기!

 

📒Day.js 역시 최상단에 import하는거 잊지말기!

const { day } = useParams();
const words = useFetch(`http://localhost:3001/words?day=${day}`); 
//🫠useParams를 받아야해서, useFetch안에 ""아니고 ``이라는점 주의!!!

 


 

 

 

 

Comments