Language/JavaScript

[React] useEffect

🥭맹2 2021. 10. 19. 16:36

처음으로 react를 사용하면서 삽질 중인데요,

useEffect으로 인해서 문제가 생긴 경험을 공유하려고 합니다.

useEffect란?

useEffect는 기본적으로 몇 가지 조건에 의해 작동하게 됩니다.

1. 페이지가 처음 렌더링 되고 난 후, useEffect는 무조건 한 번 실행됩니다.

2. useEffect에 배열로 지정한 useState의 값이 변경되면 실행되게 됩니다.

useEffect는 렌더링, 혹은 변수의 값 혹은 오브젝트가 달라지게 되면, 그것을 인지하고 업데이트를 해주는 함수입니다.
useEffect는 콜백 함수를 부르게 되며, 렌더링 혹은 값, 오브젝트의 변경에 따라 어떠한 함수 또는 여러 개의 함수들을 동작시킬 수 있습니다.

useEffect를 사용하는 여러 가지 방법

1. useEffect(() => {});

Dependency가 존재하지 않는 기본 형태입니다.
이는 dependency가 존재하지 않아 렌더링 할 때 useEffect가 한 번 실행되고,
어떠한 작은 요소라도 변화한다면 시시때때로 useEffect가 발동되어 불필요한 실행이 너무 많아집니다.

2. useEffect(() => {}, []);

useEffect를 렌더링 후 단 한번만 실행하고 싶을 때 사용하는 방법입니다.
콜백 함수 뒤에 배열을 나타내는 대괄호가 붙어있습니다.
이 곳에 dependency를 지정합니다.
하지만 아무 변수 없이 빈 대괄호가 존재하는 경우,
해당 useEffect는 렌더링 후 단 한번만 실행되고 다시는 실행되지 않습니다.

출처: https://ko.reactjs.org/docs/hooks-reference.html

3.

const [name, setName] = useState();
useEffect(() => {}, [name]);

useEffect를 렌더링 후 한 번, 그리고 배열 안에 존재하는 변수의 값이 변할 때마다 실행하는 코드입니다.
위의 예제에서는 name 변수의 값이 바뀔 경우 useEffect가 실행되게 됩니다.

저의 경우 채팅 기능을 구현하다가 아래와 같이 코드를 작성했는데요,

const Chatting = () => {
  const socket = useContext(SocketContext);
  const user = useContext(UserContext);
  const name = user.name;
  const [state, setState] = useState({ message: '', name });
  const [chat, setChat] = useState([]);

  useEffect(() => {
    if (!socket) return;

    socket.on('message', ({ name, message }) => {
      setChat((prev) => [...prev, { name, message }]);
    });
  });

  const onTextChange = (e) => {
    setState({ ...state, [e.target.name]: e.target.value });
  };

  const onMessageSubmit = (e) => {
    e.preventDefault();
    const { name, message } = state;
    socket.emit('message', { name, message });
    setState({ message: '', name });
  };

  const renderChat = () => {
    return chat.map(({ name, message }, index) => (
      <div key={index}>
        <h3>
          {name}: <span>{message}</span>
        </h3>
      </div>
    ));
  };

  return (
    <Container className="container">
      <Content className="renderChatContainer" style={{ backgroundColor: '#fff' }}>
        {renderChat()}
      </Content>
      <Form onSubmit={onMessageSubmit}>
        <input onChange={(e) => onTextChange(e)} value={state.message} name="message" />
        <button>전송</button>
      </Form>
    </Container>
  );
};

요런식으루 짜면 textChange마다 이벤트가 들어가고 그래서 socket event를 on하는 객체들이 무지막지하게 생깁니다.
이렇게 되면 아래와 같은 현상이 발생합니다.

 

속도가 체감이 되시나요 ? 점점 느려집니다.

콘솔을 찍어보면 다음과 같이 나옵니다.

(원래 gif 파일인데, 용량초과로 업로드가 되지 않아 캡처했습니다.)

이벤트마다 socket이 생성되는 것을 확인할 수 있습니다 ^_^

 

reference
https://ko-de-dev-green.tistory.com/18

'Language > JavaScript' 카테고리의 다른 글

[React] style-component 익스텐션  (0) 2021.10.20
[React] setState  (0) 2021.10.19
Number()와 parseInt() 차이  (0) 2021.08.21