리스트 API 호출하기

기본 홈페이지를 설정했으니, 이제 노트 목록을 렌더링하기 위해 API를 호출해 보겠습니다.

요청 보내기

Change indicator src/containers/Home.tsx 파일에서 const [notes, setNotes] 상태 선언을 다음으로 교체하세요.

const [notes, setNotes] = useState<Array<NoteType>>([]);

Change indicator Home 함수 상단의 상태 변수 선언 바로 아래에 다음 코드를 추가하세요.

useEffect(() => {
  async function onLoad() {
    if (!isAuthenticated) {
      return;
    }

    try {
      const notes = await loadNotes();
      setNotes(notes);
    } catch (e) {
      onError(e);
    }

    setIsLoading(false);
  }

  onLoad();
}, [isAuthenticated]);

function loadNotes() {
  return API.get("notes", "/notes", {});
}

여기서는 useEffect React Hook을 사용합니다. 이 기능은 세션에서 상태 불러오기 챕터에서 이미 다뤘습니다.

이 코드가 어떻게 동작하는지 간단히 살펴보겠습니다. 컴포넌트가 처음 로드될 때 사용자가 인증된 경우에만 /notes API에 요청을 보내 노트 목록을 가져오려고 합니다. 이 훅은 isAuthenticated에 의존하므로, useEffect 호출의 두 번째 인수로 배열 안에 isAuthenticated를 전달해야 합니다. 이는 React에게 isAuthenticated 값이 변경될 때만 훅을 다시 실행하라고 알려주는 역할을 합니다.

Change indicator React에서 useEffect를 import에 추가하세요.

import { useState, useEffect } from "react";

Change indicator 그리고 다른 의존성도 import합니다.

import { API } from "aws-amplify";
import { NoteType } from "../types/note";
import { onError } from "../lib/errorLib";

이제 결과를 렌더링해 보겠습니다.

리스트 렌더링

Change indicator renderNotesList 플레이스홀더 메서드를 다음 코드로 교체합니다.

function formatDate(str: undefined | string) {
  return !str ? "" : new Date(str).toLocaleString();
}

function renderNotesList(notes: NoteType[]) {
  return (
    <>
      <LinkContainer to="/notes/new">
        <ListGroup.Item action className="py-3 text-nowrap text-truncate">
          <BsPencilSquare size={17} />
          <span className="ms-2 fw-bold">새 노트 만들기</span>
        </ListGroup.Item>
      </LinkContainer>
      {notes.map(({ noteId, content, createdAt }) => (
        <LinkContainer key={noteId} to={`/notes/${noteId}`}>
          <ListGroup.Item action className="text-nowrap text-truncate">
            <span className="fw-bold">{content.trim().split("\n")[0]}</span>
            <br />
            <span className="text-muted">
              생성일: {formatDate(createdAt)}
            </span>
          </ListGroup.Item>
        </LinkContainer>
      ))}
    </>
  );
}

Change indicator 그리고 src/containers/Home.tsx 파일 상단에 LinkContainerBsPencilSquare 아이콘을 추가합니다.

import { BsPencilSquare } from "react-icons/bs";
import { LinkContainer } from "react-router-bootstrap";

위 코드는 다음과 같은 기능을 수행합니다.

  1. 리스트의 첫 번째 항목으로 새 노트 만들기 버튼을 항상 렌더링합니다(리스트가 비어 있어도). 이 버튼은 이전에 만든 노트 생성 페이지로 연결됩니다.

    <LinkContainer to="/notes/new">
      <ListGroup.Item action className="py-3 text-nowrap text-truncate">
        <BsPencilSquare size={17} />
        <span className="ms-2 fw-bold">새 노트 만들기</span>
      </ListGroup.Item>
    </LinkContainer>
    
  2. 버튼에는 React Icons의 Bootstrap 아이콘 세트에서 BsPencilSquare 아이콘을 사용합니다.

  3. 모든 노트 목록을 렌더링합니다.

    notes.map(({ noteId, content, createdAt }) => (...
    
  4. 각 노트 내용의 첫 줄을 ListGroup.Item 헤더로 설정합니다.

    note.content.trim().split("\n")[0];
    
  5. 노트 생성 날짜를 더 친숙한 형식으로 변환합니다.

    !str ? "" : new Date(str).toLocaleString()
    
  6. LinkContainer 컴포넌트는 각 항목을 적절한 URL로 이동시킵니다.

이제 브라우저로 이동하면 리스트가 표시되는 것을 확인할 수 있습니다.

홈페이지 리스트 로드 스크린샷

각 항목을 클릭하면 적절한 _noteId_가 포함된 URL이 생성됩니다. 현재는 이 URL들이 404 페이지로 이동하지만, 다음 섹션에서 이 문제를 해결할 예정입니다.

다음으로 사용자가 노트를 보고 편집할 수 있도록 구현할 것입니다.