-
[React.js] React 기초5 (+ useEffect, fetch, react Hooks, useNavigate, PUT, DELETE, POST)React 2022. 10. 30. 17:25
* 렌더링 : 리액트에서는 컴포넌트가 현재 props와 state의 상태에 기초하여 UI를 어떻게 구성할지 컴포넌트에게 요청하는 작업이다.
DayList.js
import { useEffect,useState } from "react"; import { Link } from "react-router-dom"; import dummy from "../db/data.json"; export default function DayList(){ const [days, setDays]=useState([]); // API에서 데이터를 갖고와서 바꿔주는 방식으로 하겠다 // 따라서 데이터가 바뀌면 자동으로 렌더링 될 것이다. const [count, setCount] = useState(0); function onclick(){ setCount(count+1); } function onclick2(){ setDays([ ...days, { id:Math.random(), day:1, } ]) } useEffect(()=>{ console.log("Count change") }, [count]); // 어떤 상태값이 바뀌었을 때 동작하는 함수를 작성할 수 있다. // 두번째 매개변수를 넣어주면, 그 매개변수(의존성 배열)가 바뀌었을 때만, 함수가 실행된다. // 이것을 의존성 배열이라고 한다. // 즉, 여기서는 카운드 값이 바뀔 때만 콘솔로그가 실행된다. return ( <> <ul className="list_day"> {days.map(day=>( <li key={day.id}> <Link to={`/day/${day.day}`}>Day {day.day}</Link> {/* day.day는 data.json파일의 days 객체에서 day키값이 가진 값이다. */} </li> ))} </ul> <button onClick={onclick}>{count}</button> <button onClick={onclick2}>day change</button> </> ); } // 맵은 배열을 받아서 또다른 배열로 반환해주는 것인데, // 이떄 반환되는 요소를 JSX 형태로 작성해주면 된다. // key 반복되는 요소의 고유한 값으로 전달해야 되서 여기서는 day.id
* API 비동기 통신 :
동기 통신은 전체 페이지를 reload하기 때문에, 서버의 부하가 커지고 시간도 오래 걸린다. 또한 페이지가 리로드 되는 동안에는 다른 데이터를 처리할 수 없다. 반대로 비동기 통신은 요청을 보낸 후에는 응답과는 상관없이 동작한다.
* AJAX : Asynchronous JavaScript and XML 으로, 빠르게 동작하는 동적인 웹 페이지를 만들기 위한 개발 기법이다. 비동기성으로 페이지 전체를 리로드 하지 않고, 사용자의 이벤트가 발생하면 페이지의 일부만 업데이트한다. 서버와의 통신을 위해 XMLHttpRequest 객체를 사용한다. JSON, XML, HTML, 일반 텍스트 등 다양한 포맷을 주고 받을 수 있다.
* Fetch API : XMLHttpRequest를 대체하며 비동기 http 요청을 좀 더 쓰기 편하게 해주는 API이다. 첫번째 인자는 URL, 두 번째 인자는 옵션 객체를 받는다. Promise 기반으로 동작하며 fetch의 기본 응답 결과는 Response 객체이다.
DayList.js
import { useEffect,useState } from "react"; import { Link } from "react-router-dom"; import dummy from "../db/data.json"; export default function DayList(){ const [days, setDays]=useState([]); // API에서 데이터를 갖고와서 바꿔주는 방식으로 하겠다 // 따라서 데이터가 바뀌면 자동으로 렌더링 될 것이다. // 렌더링이 완료되고, 후에 최초 한번만 API를 호출해주면 된다. // 이때는 의존성 배열에 빈 배열을 전달해주면 된다. useEffect(()=>{ fetch('http://localhost:3001/days') // API경로를 적어주면, 프로미스가 반환된다. .then(res => { //그러면 then을 이용해서 리턴해준다. return res.json() //여기서 리스폰스는 http 응답이기 때문에, 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> {/* day.day는 data.json파일의 days 객체에서 day키값이 가진 값이다. */} </li> ))} </ul> ); } // 맵은 배열을 받아서 또다른 배열로 반환해주는 것인데, // 이떄 반환되는 요소를 JSX 형태로 작성해주면 된다. // key 반복되는 요소의 고유한 값으로 전달해야 되서 여기서는 day.id
Day.js
import dummy from "../db/data.json"; //더미 데이터 임포트 import { useParams } from "react-router-dom"; import Word from "./Word"; import { useEffect } from "react"; // url이 포함된 값을 얻을 때는 userParams 를 사용 export default function Day(){ //dummy.words const day=useParams().day; //const wordList = dummy.words.filter(word=>word.day===Number(day)); //dummy.words 에서 날짜가 1인 것만 필터를 통해서 출력하겠다 const [words, setWords]=useState([]); useEffect(()=>{ fetch('http://localhost:3001/words') // API경로를 적어주면, 프로미스가 반환된다. .then(res => { //그러면 then을 이용해서 리턴해준다. return res.json() //여기서 리스폰스는 http 응답이기 때문에, json으로 바꿔준다. }) .then(data=>{ setDays(data); }) }, []);//빈 배열을 넣어서 한번만 실행 return <> <h2>Day {day}</h2> <table> <tbody> {words.map(word=>( <Word word={word} key={word.id} /> ))} </tbody> </table> </> }
* react js code snippets 이라는 vs code 확장 플러그인으로 단축키를 이용해 쉽게 코드를 작성할 수 있다.
rsf -> 함수형 컴포넌트
form 태그로 감싸져 있어서, 저장 버튼을 누르면 페이지 전체가 새로고침이 된다.
반드시 저장을 해야 자동으로 렌더링이 된다.
CreateWord.js
import useFetch from "../hooks/useFetch"; import {useRef, useState} from "react"; import { useNavigate } from "react-router-dom"; export default function CreateWord() { const days=useFetch("http://localhost:3002/days"); const navigate = useNavigate(); const [isLoading, setIsLoading] = useState(false); function onSubmit(e){ e.preventDefault(); //새로고침되지 않도록 기본기능을 막음 if(!isLoading){ setIsLoading(true); fetch(`http://localhost:3002/words/`, { method:"POST", headers:{ "Content-Type":"application/json", }, body: JSON.stringify({ day : dayRef.current.value, eng : engRef.current.value, kor : korRef.current.value, //current 속성을 이용해서 해당 요소에 접근하고, value로 인풋에 저장된 값을 가져왔다 isDone : false }), }) .then(res=>{ if(res.ok){ alert("생성이 완료 되었습니다!") navigate(`/day/${dayRef.current.value}`) setIsLoading(false); } }) } } const engRef = useRef(null); const korRef = useRef(null); const dayRef = useRef(null); //useRef는 돔에 접근하여, 스크롤 위치를 확인하거나 포커스를 줄 때 사용할 수 있다. return ( <form onSubmit={onSubmit}> <div className="input_area"> <label>Eng</label> <input type="text" placeholder="computer" ref={engRef}/> </div> <div className="input_area"> <label>Kor</label> <input type="text" placeholder="컴퓨터" ref={korRef}/> </div> <div className="input_area"> <label>Day</label> <select ref={dayRef}> {days.map(day=>( <option key={day.id} value={day.day}> {day.day} </option> ))} </select> </div> <button style={{ opacity : isLoading ? 0.3 : 1 }} >{isLoading ? "Saving..." : "저장"}</button> </form> ); }
CreateDay.js
import useFetch from "../hooks/useFetch" import { useNavigate } from "react-router-dom"; export default function CreateDay(){ const days=useFetch("http://localhost:3002/days"); const navigate = useNavigate(); function addDay(e){ fetch(`http://localhost:3002/days/`, { method:"POST", headers:{ "Content-Type":"application/json", }, body: JSON.stringify({ day : days.length+1 }), }) .then(res=>{ if(res.ok){ alert("생성이 완료 되었습니다!") navigate(`/`) } }) } return ( <div> <h3>현재 일수 : {days.length}</h3> <button onClick={addDay}>Day 추가</button> </div> ) }
외부 참조 링크
https://www.youtube.com/watch?v=SMKRXZljBt8&list=PLZKTXPmaJk8J_fHAzPLH8CJ_HO_M33e7-&index=12
https://yceffort.kr/2022/04/deep-dive-in-react-rendering
Home
yceffort
yceffort.kr
[JS🐣] 비동기 통신 이해하기(XHR과 Fetch API)
브라우저에서 폼을 채우고 이를 웹 서버로 제출(submit)하면 웹 서버는 요청된 내용에 따라서 데이터를 가공하여 새로운 웹페이지를 작성하고 응답으로 되돌려준다.전체 페이지를 reload하기 때문
velog.io
[VS CODE] Reactjs Code Snippets
## Reactjs Code Snippets의 단축키 단축키 설명 rcc 클래스 컴포넌트 생성 rrc 클래스 컴포넌트와 react-redux 리덕스를 연결해서 생성 rccp 클래스 컴포넌트와 prop type들을 클래스 뒤에 생성 rcjc import와 e..
ossam5.tistory.com
'React' 카테고리의 다른 글
[React.js] 리액트 문법 1 (+ JSX, DOM, API) (0) 2022.12.31 [React Project] 1. 주제 선정 & 일정 수립 (0) 2022.10.31 [React.js] React 기초4 (+ react-router-dom, REST API, JSON server) (0) 2022.10.30 [React.js] React 기초3 (+ props, 더미 데이터 구현, map(), filter()) (0) 2022.10.28 [React.js] React 기초2 (+ css 파일, 이벤트 처리, state) (0) 2022.10.27