useMemo, useCallback , useFetch, useInput 실습예제

돌리의 하루·2023년 3월 23일
0
post-thumbnail

useMemo : 함수의 값을 기억한다

import React, { useState } from "react";
import "./styles.css";
import { add } from "./add";

export default function App() {
  const [name, setName] = useState("");
  const [val1, setVal1] = useState(0);
  const [val2, setVal2] = useState(0);
  const answer = add(val1, val2);

  return (
    <div>
      <input
        className="name-input"
        placeholder="이름을 입력해주세요"
        value={name}
        type="text"
        onChange={(e) => setName(e.target.value)}
      />
      <input
        className="value-input"
        placeholder="숫자를 입력해주세요"
        value={val1}
        type="number"
        onChange={(e) => setVal1(Number(e.target.value))}
      />
      <input
        className="value-input"
        placeholder="숫자를 입력해주세요"
        value={val2}
        type="number"
        onChange={(e) => setVal2(Number(e.target.value))}
      />
      <div>{answer}</div>
    </div>
  );
}

위의 코드를 useMemo를 이용해서 최적화해보자!

import React, { useState } from "react";
import "./styles.css";
import { add } from "./add";
import { useMemo } from "react";

export default function App() {
  const [name, setName] = useState("");
  const [val1, setVal1] = useState(0);
  const [val2, setVal2] = useState(0);
 const answer = useMemo(() => add(val1, val2), [val1, val2]);

  return (
    <div>
      <input
        className="name-input"
        placeholder="이름을 입력해주세요"
        value={name}
        type="text"
        onChange={(e) => setName(e.target.value)}
      />
      <input
        className="value-input"
        placeholder="숫자를 입력해주세요"
        value={val1}
        type="number"
        onChange={(e) => setVal1(Number(e.target.value))}
      />
      <input
        className="value-input"
        placeholder="숫자를 입력해주세요"
        value={val2}
        type="number"
        onChange={(e) => setVal2(Number(e.target.value))}
      />
      <div>{answer}</div>
    </div>
  );
}

useCallback : 함수를 기억한다

  • darkmode 버튼 눌러도 console.log('아이템을 가져옵니다')가 더이상 찍히지 않음
//App.js
import { useCallback, useState } from "react";
import "./styles.css";
import List from "./List";

export default function App() {
  const [input, setInput] = useState(1);
  const [light, setLight] = useState(true);

  const theme = {
    backgroundColor: light ? "White" : "grey",
    color: light ? "grey" : "white"
  };

  const getItems = useCallback(() => [input + 10, input + 100], [input]);

  const handleChange = (event) => {
    if (Number(event.target.value)) {
      setInput(Number(event.target.value));
    }
  };

  return (
    <>
      <div style={theme} className="wall-paper">
        <input
          type="number"
          className="input"
          value={input}
          onChange={handleChange}
        />
        <button
          className={(light ? "light" : "dark") + " button"}
          onClick={() => setLight((prevLight) => !prevLight)}
        >
          {light ? "dark mode" : "light mode"}
        </button>
        <List getItems={getItems} />
      </div>
    </>
  );
}
import { useState, useEffect } from "react";

function List({ getItems }) {
  /* Initial state of the items */
  const [items, setItems] = useState([]);

  useEffect(() => {
    console.log("아이템을 가져옵니다.");
    setItems(getItems());
  }, [getItems]);

  /* Maps the items to a list */
  return (
    <div>
      {items.map((item) => (
        <div key={item}>{item}</div>
      ))}
    </div>
  );
}

export default List;

useFetch : 여러 url을 fetch할 때 쓸 수 있다

//App.js
import useFetch from "./util/useFetch";
import "./styles.css";

//useFetch, useInput, useForm : custom hook
export default function App() {
  const fetchData = useFetch("data.json");

  return (
    <div className="App">
      <h1>To do List</h1>
      <div className="todo-list">
        {fetchData &&
          fetchData.todo.map((el) => {
            return <li key={el.id}>{el.todo}</li>;
          })}
      </div>
    </div>
  );
}
//useFetch.js
import { useEffect, useState } from "react";

const useFetch = (fetchUrl) => {
  const [data, setData] = useState();

  useEffect(() => {
    fetch(fetchUrl, {
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      }
    })
      .then((response) => {
        return response.json();
      })
      .then((myJson) => {
        setData(myJson);
      })
      .catch((error) => {
        console.log(error);
      });
  }, [fetchUrl]);

  //loading, error
  return data;
};

export default useFetch;

useInput : 여러 input에 의한 상태 변경을 할 때 쓸 수 있다

// App.js

import { useState } from "react";
import useInput from "./util/useInput";
import Input from "./component/Input";
import "./styles.css";

export default function App() {
  
  const [fistValue, firstBind, firstReset] = useInput("");
  const [lastValue, lastBind, lastReset] = useInput("");
  const [nameArr, setNameArr] = useState([]);

  const handleSubmit = (e) => {
    e.preventDefault();
    setNameArr([...nameArr, `${fistValue} ${lastValue}`]);
    firstReset();
    lastReset();
  };

  return (
    <div className="App">
      <h1>Name List</h1>
      <div className="name-form">
        <form onSubmit={handleSubmit}>
          <Input labelText={"성"} value={firstBind} />
          <Input labelText={"이름"} value={lastBind} />
          <button>제출</button>
        </form>
      </div>
      <div className="name-list-wrap">
        <div className="name-list">
          {nameArr.map((el, idx) => {
            return <p key={idx}>{el}</p>;
          })}
        </div>
      </div>
    </div>
  );
}
// .component/Input.js

function Input({ labelText, value }) {
  return (
    <div className="name-input">
      <label>{labelText}</label>
      <input {...value} type="text" />
    </div>
  );
}

export default Input;
// .util/useInput.js

import { useState } from "react";

function useInput(initialValue) {
  const [value, setValue] = useState(initialValue);

  const bind = {
    value,
    onChange: (e) => {
      setValue(e.target.value);
    }
  };

  const reset = () => {
    setValue(initialValue);
  };
  
//return 해야 하는 값은 배열 형태의 값
  return [value, bind, reset];
}

export default useInput;
profile
진화중인 돌리입니다 :>

0개의 댓글