Skip to content

study-react-from-scratch-hoco/frogsoo

Repository files navigation

HOCO React 스터디

지난 주차

1주차 2주차

3주차

전통적인 React 렌더링의 한계

데이터를 API로 부터 가져와 DOM에 렌더하는 세 가지 접근법

  • Fetch-on-Render
function ProfilePage() {
  const [user, setUser] = useState(null);
  useEffect(() => {
    fetchUser().then((u) => setUser(u));
  }, []);
  if (user === null) {
    return <p>Loading profile...</p>;
  }
  return (
    <>
      <h1>{user.name}</h1>
      <ProfileTimeline />
    </>
  );
}
  • 초기 렌더 후 데이터 fetching, 데이터 준비되면 useState를 통한 업데이트

  • 컴포넌트가 렌더된 후에 fetching -> waterfall 발생 가능

  • Fetch-Then-Render

// Wrapping all data fetching
function fetchProfileData() {
  return Promise.all([fetchUser(), fetchPosts()]).then(([user, posts]) => {
    return { user, posts };
  });
}
// Using it in our Component
function ProfilePage() {
  const [user, setUser] = useState(null);
  const [posts, setPosts] = useState(null);
  useEffect(() => {
    promise.then((data) => {
      setUser(data.user);
      setPosts(data.posts);
    });
  }, []);
  if (user === null) {
    return <p>Loading profile...</p>;
  }
  return (
    <>
      <h1>{user.name}</h1>
      <ProfileTimeline posts={posts} />
    </>
  );
}
  • fetching과 컴포넌트를 분리, waterfall 방지

  • fetching 시작, fetching 완료, redering 시작

  • 사용자는 그 동안 UI를 볼 수 없음

  • Render as you fetch(Suspense)

    • fetching 시작, 렌더링 시작, fetching 완료
    • 거의 즉시 렌더링을 시작할 수 있음!!

React Suspense의 작동 방식

  • try / catch를 통해 로딩 중을 알리기 위해 throw
const resourceCache = {};
const createResource = (asyncTask, key) => {
  // 우선 캐시에 키가 존재하는지 체크한다.
  // 존재한다면, 캐시된 값을 리턴

  if (resourceCache[key]) return resourceCache[key];
  // 아니라면 프로미스를 핸들링해야...
  throw { promise: asyncTask(), key };
};
  • fallback UI

    • React.createElement에서 이걸 catch!
    • fallback UI를 보여준다!
const React = {
  createElement: (tag, props, ...children) => {
    if (typeof tag === "function") {
      try {
        return tag(props, ...children);
      } catch ({ promise, key }) {
        // resolved 되었을 때와 rejected 되었을 때를 처리한다.
        promise.then((value) => {
          resourceCache[key] = value;
          reRender();
        });
        promise.catch((error) => {
          console.error(error);
        });
        // 여기서 VirtualDOM으로 분기한다.
        // 이제 바로 렌더가능하다~!!
        return { tag: "h2", props: null, children: ["loading your image"] };
      }
    }

    const el = { tag, props, children };
    return el;
  },
};
  • 캐싱

    • 이미 값이 있으면 해당 값을 반환, 없으면 프로미스를 던진다!
  • 재렌더링

About

react 스터디

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published