[React] solo project: todo app

KoEunseo·2022년 10월 18일
0

project

목록 보기
1/37
post-custom-banner

솔로프로젝트를 했다.
기존에 디자인하고 껍데기까지만 만들어놨던 상태였고!
오늘은 기능을 넣었다.

Create Read Update Delete 기능을 하나씩 구현해야 한다.

todo를 구현하면서 만났던 에러들을 기록해보고자 한다.

사용한 도구들

  1. react
    Hook: useState, useEffect
    Suspense, lazy
  2. json-server API
  3. style : fontawsome, googlefont, styled-component

1. fetch undefined error

Q fetch를 해서 데이터를 받아왔는데 fetch 내에서 콘솔을 찍으면 데이터가 제대로 나오는데,
화면에 렌더링하려고 하면 undefined가 나오는 에러가 발생했다.
undefined니까 당연히 map이 안됨.
A fetch로 받아온 데이터를 useState로 받아 해결

//App.js
const [todos, setTodos] = useState();

useEffect(() => {
  fetch('http://localhost:3001/todos')
    .then(res => {
    if (!res.ok) {
      throw Error('could not fetch the data for that resource');
    }
    return res.json();
  })
    .then(data => {
    setTodos(data);
  })
    .catch(err => {
    console.log(err);
  })
}, [])

2. Input value error

Q input에 value를 주었더니 입력이 먹지 않는 에러가 발생. custom hook을 사용했었는데 뭔가 안됐는지...
A custom hook 말고 그냥 input에 onchange 이벤트를 넣어주어 해결

//CreateTodo.js
const CreateTodo = () => {
  const [text, setText] = useState("");
  const onChange = e => setText(e.target.value);

  const handleSubmit = (e) => {
    e.preventDefault();
    const data = {
      text,
      done: false
    }
    fetch('http://localhost:3001/todos/', {
      method: "POST",
      headers: { "Content-type": "application/json" },
      body: JSON.stringify(data)
    })
      .then(() => window.location.reload())
      .catch(error => console.log(error))
  }

  return <CreateWrap>
    <form onSubmit={handleSubmit}>
      <input type="text" label={"내용"}
        onChange={onChange}
        value={text} />
      <button>ADD TODO</button>
    </form>
  </CreateWrap>
}

3. styled component를 컴포넌트에 넣지 말것

컴포넌트 바깥에 두어야한다!! 이상하고 신경쓰이는 에러가 발생함...

4. checked button click error

Q 체크버튼을 두번 눌러야 true/false 변환이 되는 에러 발생
A handler와 fetch를 분리해주었다. fetch를 useEffect내에서 실행해줌. 이 과정에서 CreateTodo.js에서처럼 window.location.reload()를 하면 무한리로딩이 발생하더라. 주의할것!!

//TodoItem.js
const TodoItem = ({ id, done, text }) => {
  const [isChecked, setIsChecked] = useState(done);

  const handleDoneClick = () => {
    setIsChecked(!isChecked);
  }

  useEffect(() => {
    fetch(`http://localhost:3001/todos/${id}`, {
      method: "PATCH",
      headers: { "Content-type": "Application/json" },
      body: JSON.stringify({ done: isChecked })
    })
      .then(() => {
        console.log(isChecked)
      })
      .catch(error => console.log(error))
  }, [isChecked])


  const handleDeleteBtn = (e) => {
    fetch(`http://localhost:3001/todos/${id}`, {
      method: "DELETE"
    }).then(() => window.location.reload())
      .catch(err => console.log(err))
  }

  return <List>
    <div>
      <FontAwesomeIcon icon={faSquareCheck}
        className={isChecked ? "isChecked" : ""}
        onClick={handleDoneClick} />
      <span>{text}</span>
    </div>
    <div>
      <FontAwesomeIcon icon={faPenNib} />
      <FontAwesomeIcon icon={faCircleXmark} className="deleteBtn"
        onClick={handleDeleteBtn} />
    </div>
  </List>
}

시연장면

아직 수정은 구현하지 못했다...
구현하면 수정하도록 하겠다!!

++ json-server 열기
json-server --watch db.json --port 3001

profile
주니어 플러터 개발자의 고군분투기
post-custom-banner

0개의 댓글