리액트 사이드 이팩트

하비·2024년 2월 2일
0
post-thumbnail

사이드 이팩트


DOM에 적어서 적용을 해도 리액트에서는 반영이 안됨

서버 렌더링 과정

useEffect 훅

  1. 셋업 함수(콜백 함수)

2. 종속성 배열(조건처리)

어떤 경우에 함수가 실행될 지 정해줌

3. 로컬 스토리지 읽기/쓰기(사이드 이팩트)

function Exercise() {
  // 로컬 스토리지 데이터 읽기 -> 컴포넌트 상태로 관리
  // 로컬 스토리지에서 데이터를 읽거나 쓰는 건 비동기!
  // ❌
  // const username = localStorage.getItem('username');
  // const [uname] = useState(username);
  //✔
  const [username] = useState(() => {
    const username = localStorage.getItem('username');
    return username;
  });
  console.log(username);

클린업의 중요성

function Message({ message }) {
  useEffect(() => {
    const handleMove = (e) => {
      console.log({ x: e.clientX, y: e.clientY });
    };
    //이벤트 청취(구독)
    globalThis.addEventListener('mousemove', handleMove); 
  });
  return <p>{message}</p>;
}

클린업을 안할 시 없어진 후에도 계속 동작하게 됨
때문에 동작 취소를 넣어줘야함

function Message({ message }) {
  useEffect(() => {
    const handleMove = (e) => {
      console.log({ x: e.clientX, y: e.clientY });
    };
    //이벤트 청취(구독)
    globalThis.addEventListener('mousemove', handleMove);
    //이벤트 청취해제(구독 취소)
    return function cleanup() {
      globalThis.removeEventListener('mousemove', handleMove);
    };
  }, []);
  return <p>{message}</p>;
}

데이터의 관리

AbortController

MDN문서

async function fetchProducts(options) {
  try {
    const response = await fetch(
      `${API}/api/collections/products/records`,
      options
    );
    const data = await response.json();
    return data;
  } catch (error) {
    if (!(error instanceof DOMException)) {
      throw new Error(error);
    }
  }
}
function Exercise() {
  const [tableContents] = useState([]);
  useEffect(() => {
    const controller = new AbortController();

    fetchProducts({ signal: controller.signal }).then((data) =>
      console.log(data)
    );
    //신호를 통해 중복된 요청일 경우 웹 요청을 취소(abort)
    // 클린업
    return () => {
      //네트워크 요청 취소
      controller.abort();
    };
  });

개발 과정에서 쓸모 없는 네트워크 요청이 들어가지 않도록 하는 api.
한번 요청된 네트워크 요청은 두번 되지 않는다.
이 경우 DOMexception이라는 에러가 생기는데, 이것이 뜨지 않도록 하기 위해 catch에서 이 에러를 제해 주면된다.

쓰는 방법:
1. AbortController()생성자 만들기
2. fetch(url, {controller.abort()}) 설정
3. controller.abort()로 요청 취소
4. try catch 구문에서 error의 DOMexception 경우 에러에서 제외
왜쓰는걸까?
개발 단계에서 생기는 불필요한 요청을 제거하기 위해
그리고 이벤트리스너에서도 사용할 수 있다.

const controller = new AbortController();
const { signal } = controller;
document.addEventListener('click', () => {
  console.log('클릭 이벤트 발생');
}, { signal });
// 필요할 때 이벤트 리스너 취소
controller.abort();

useRef

element 요소에 ref를 넣고 안에 콜백 함수를 넣어주면, 함수의 매개변수로 해당 DOM객체가 전달됨

의문...


40-3번 예제의 table 아래에 col 태그를 넣었는데 이런 에러가 떴다...
colgroup으로 묶어놔야함...

profile
개발자를 꿈꾸는 하비입니다

0개의 댓글