React-Native/공부

1.React-Native(리액트 네이티브) Side-effect

바코더 2021. 2. 26. 10:45

1.Side-effect

import React, { Fragment, useEffect, useState } from "react";
import { Promise } from "bluebird";

Promise.config({ cancellation: true });

function fetchUser() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({ id: 1, name: "Adam" });
    }, 1000);
  });
}

export default function User() {
  const [id, setId] = useState("loading...");
  const [name, setName] = useState("loading...");

  useEffect(() => {
    const promise = fetchUser().then(user => {
      setId(user.id);
      setName(user.name);
    });

    return () => {
      promise.cancel();
    };
  });

  return (
    <Fragment>
      <p>ID: {id}</p>
      <p>Name: {name}</p>
    </Fragment>
  );
}

UseEffect 는 Lifecycle 대신에 사용할 수 있는 Hook 의 기능이다. UseEffect의 function 은 component 의 rendering 이 완성 된 뒤에 call되어서 Coponent Rendering 되기 전에 data의 fetch 가 되어서 발생할 수 있는 에러를 방지해준다.

UseEffect 말고도 또 체크해야 할 부분이 있는데, 바로 promise cancel 부분이다.

 

 

 

2.promise cancel

useEffect(() => { const promise = fetchUser().then(user => {
	setId(user.id); setName(user.name); }); 
	return () => { promise.cancel(); }; 
});

 

useEffect 로 Component 가 Mount 될때 fetchUser를 실행해서 사용자 정보를 불러오는 도중, 다른 화면을 가는 등의 행동을 통해 Component 가 UnMount 된다면 Api는 그대로 실행되고, 변경할 state 값이 없어서 에러가 난다. 쓰레드의 자원 관리와 에러 방지를 위해, return()=>{promise.cancel()} 을 통해 Component 가 Unmound 되면 Api Call 을 취소할 수 있다.

3.promise clean

const [resolved, setResolved] = useState(false); useEffect(() => { // ...the effect code... return () => { // ...the cleanup code that depends on "resolved" } }, [resolved]);

const [resolved, setResolved] = useState(false); 
	useEffect(() => { // ...the effect code...
return () => { /
	/ ...the cleanup code that depends on "resolved" } }, 
[resolved]);

resolved 를 clean으로 호출하면 결과값이 나올때 마다 clean 된다. 만일 resolve의 값이 변하지 않으면 clean이 호출되지 않는다.

만일 Component 가 처음 Mount 될때만 FechApiData를 하고 싶다면 [], Empty Array 를 주면 된다.

  useEffect(() => {
    const promise = fetchUser().then(user => {
      setId(user.id);
      setName(user.name);
    });

    return () => {
      promise.cancel();
    };
  }, []);

 

만일 []를 지운다면, fechUser 가 여러번 불려지는 걸 알 수 있다. 이건 state가 render 될 때마다 fetch가 실행되어서 그렇다. 처음 state 의 초기값이 loading 이었다가 1초 뒤에 각각 set된 값으로 변경되고 re-render가 되어서 다시 fechdata가 불려진다. state 값이 2개니 2번 rerender 되고 fetchUser는 총 3번 불려지는 것이다.

만일 setState가 하나라면,

const promise = fetchUser().then(user => { setId(user.id); });

1번 re-render 되기 때문에 총 2번 fechUser가 호출된다.

한번만 render 될때마다 다시 호출되는 것이 아닌 한번 호출은 []을 통해 clean 을 해주는 것이 좋다.