๐Ÿ“–[React] ๋งˆ๋ฌด๋ฆฌ ์ž‘์—…

ํ˜ฑยท2022๋…„ 10์›” 18์ผ

React

๋ชฉ๋ก ๋ณด๊ธฐ
28/28

โœ”๏ธ ๋А๋ฆฐ ์ธํ„ฐ๋„ท ํ™˜๊ฒฝ ํ™•์ธ

Crome ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์— Network์—์„œ Online->Slow3G

๋А๋ฆฐ ์ธํ„ฐ๋„ท ํ™˜๊ฒฝ TEST ๊ฐ€๋Šฅ
๋А๋ฆฐ ์ธํ„ฐ๋„ท ํ™˜๊ฒฝ์—์„œ ์ ‘์†ํ•˜๋ฉด, ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ๋ชปํ•˜๊ณ  ํ™”๋ฉด์„ ๋น ์ ธ๋‚˜๊ฐˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ™•์ธํ•ด์•ผ ํ•จ : ์ดˆ๊ธฐ๊ฐ’์— ๋งž์ถฐ์„œ!

์˜ˆ์‹œ

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;
}

const [data, setData] =useState([]); ์ดˆ๊ธฐ๊ฐ’์ด ๋นˆ ๋ฐฐ์—ด
๋”ฐ๋ผ์„œ, ์ดˆ๊ธฐ๊ฐ’์ด๋ฉด, ๋กœ๋”ฉ์ค‘์ด๋ผ๋Š” ํ™”๋ฉด์„ ๋„์›Œ์ฃผ๊ธฐ

DayList.js
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>
    </>
  );
}

โœ”๏ธ Data์™€ ํ†ต์‹  ์ค‘์ผ ๋•Œ๋Š” ๋ฒ„ํŠผ ํด๋ฆญ ๋ถˆ๊ฐ€ํ•˜๋„๋ก ์„ค์ •

CreateWord.js
import React, { useState } from "react";
import { useRef } from "react";
import { useHistory } from "react-router-dom";
import useFetch from "../hooks/useFetch";

export default function CreateWord() {
  const days = useFetch("http://localhost:3001/days");
  const history = useHistory();
  const [isLoading, setIsLoading] = useState(false);
  //isLoading์ด false ์ผ ๋•Œ๋งŒ onSubmitํ•จ์ˆ˜ ์‹คํ–‰

  function onSubmit(e) {
    e.preventDefault();

    //isLoading ์ด false์ด๋ฉด ํ•จ์ˆ˜ ์‹คํ–‰
    if (!isLoading) {
      setIsLoading(true); 
      //์‹คํ–‰๋˜๋ฉด true๋กœ ์ „ํ™˜
      fetch(`http://localhost:3001/words/`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          day: dayRef.current.value,
          eng: engRef.current.value,
          kor: korRef.current.value,
          isDone: false,
        }),
      }).then((res) => {
        if (res.ok) {
          alert("์ƒ์„ฑ์ด ์™„๋ฃŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค");
          history.push(`/day/${dayRef.current.value}`);
          setIsLoading(false); //๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฏ€๋กœ
        }
      });
    }
  }
  const engRef = useRef(null);
  const korRef = useRef(null);
  const dayRef = useRef(null);

  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>
      style=
      {{
        opacity: isLoading ? 0.2 : 1,
      }}
      <button>{isLoading ? "Saving..." : " ์ €์žฅ"}</button>
	//isLoading์ด true(Loading ์ค‘) ์ผ๋•Œ๋Š”, ๋ฒ„ํŠผ์„ Saving์œผ๋กœ ๋ฐ”๊ฟ”์คŒ
    </form>
  );
}

์ฝ”๋”ฉ์•™๋งˆ React ๊ฐ•์˜ ๋!
์ด์ œ, ๋ณต์Šต!! + ์ง์ ‘ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋งŒ๋“ค์–ด๋ณด๊ธฐ!!
React์— ๋Œ€ํ•œ ๊ฐœ๋…์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ํ›‘๋Š” ๋ฐ ์ •๋ง ๋„์›€์ด ๋œ ๊ฒƒ ๊ฐ™๋‹ค.
์งง๊ฒŒ๋งŒ ๋งํ•˜์ž๋ฉด ์ง„์งœ UX, UI์˜ ๊ตฌํ˜„์„ ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ์ œ๋Œ€๋กœ ๋งก๊ณ  ์žˆ๊ตฌ๋‚˜๋ฅผ ์ง์ ‘์ ์œผ๋กœ ๋А๋‚„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ ๊ฐ•์˜์˜€๊ณ , ๋„ˆ๋ฌด ์žฌ๋ฏธ์žˆ์—ˆ๋‹ค. ๋ญ”๊ฐ€ ์•ž๊ธธ์ด ํŠธ์ธ ๋А๋‚Œ์ด๋ผ...!
์ด์ œ ๋๋‚˜๊ณ  ํ•  ์ผ...

  • ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ๊ตฌํ˜„ํ•ด๋ณด๊ธฐ
  • Github์— ์—…๋กœ๋“œ
  • ๊ณผ์ œ: Day๋ฅผ ์ž˜๋ชป ๋งŒ๋“ค์—ˆ์„ ๋•Œ, Day๋ฅผ ์‚ญ์ œ + ๊ฐ Day์—์„œ ํ™”์‚ดํ‘œ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‹ค๋ฅธ Day ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋„๋ก
  • ์ž์„ธํ•œ ๋ฆฌ๋ทฐ ์ž‘์„ฑ
profile
new blog: https://hae0-02ni.tistory.com/

0๊ฐœ์˜ ๋Œ“๊ธ€