![다시 시작하는 리액트 - 리액트 실무 기초 3](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWPV4u%2Fbtr6tVzQVgG%2F7D7kq8PPrEhiXC9H3He0Sk%2Fimg.png)
3-1. Event Listener
- 이벤트 리스너 : 사용자가 어떤 행동(=이벤트)을 하는 지 아닌 지 지켜보다가 알려주는 것.
( 대표적 : 마우스 클릭, 터치, 마우스 오버, 키보드 누름 등 )
이벤트 리스너는 <div onClick={}>에서처럼 엘리먼트에 직접 넣어줄 수도 있지만,
이번에는 addEventListener를 통해 추가해볼 거임.
동그라미 안에 텍스트를 한 줄 넣고 텍스트를 넣어줄 건데
동그라미에 마우스를 올렸을 때 동그라미의 색이 변하고, 텍스트에 마우스를 올렸을 때 텍스의 색이 변하도록 할 거임.
- App.js
import React from "react";
import styled from "styled-components";
import Text from "./Text";
const Wrap = styled.div`
width: 100vw;
height: 100vh;
text-align: center;
`;
const Circle = styled.div`
width: 250px;
height: 250px;
background-color: green;
margin: auto;
border-radius: 250px;
`;
class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.circle = React.createRef(null);
}
componentDidMount = () => {
console.log(this.circle);
// {current: div}
};
componentWillUnmount = () => {};
render() {
return (
<Wrap>
<Text />
<Circle ref={this.circle} />
</Wrap>
);
}
}
export default App;
- Text.js
import React from "react";
import styled from "styled-components";
const TextH1 = styled.h1``;
export default function Text() {
const text = React.useRef(null);
return <TextH1 ref={text}>텍스트 입니다!</TextH1>;
}
구독하다 => event listener를 추가해주는 것을 구독한다고 표현함.
- 먼저, 어떤 행위(event)가 일어나면 그 다음에 뭘 할지 결정해주는 함수를 민들어야 함.
우리는 this.circle.current에 mouseover 했을 때 hoverEvent 함수가 실행되도록 할 거임.
먼저 함수가 실행될 때 event target과 this.circle.current가 같은 대상인지 확인하고,
같은 대상이 맞다면 this.circle.current.style.background = "yellow";
코드를 작성하여 hoverEvent 함수가 실행되면 원의 색이 노랑색으로 바뀌게 할 거임.
- 위에서 element에 event listener를 추가하는 것이 아닌,
addEventListener를 이용해서 event listener를 추가하겠다고 했으니
mount가 끝난 후인 componentDidMount에 addEventListener 코드를 작성해줌.
(mount가 끝난 후 => render를 통하여 컴포넌트가 실제 Dom에 올라간(부착된) 후)
addEventListener(어떤 이벤트가 실행될지, 어떤 행동을 할 것인지 함수 형태(콜백함수로 추가해도 됨))
- clean up :
컴포넌트가 사라졌다가 생기면 event listener가 또 생기게 됨.
mouseover를 한 번만 했음에도 불구하고 mouseover를 한 100번 한 것처럼 event가 계속 올라갈 수도 있다는 얘기.
이러한 현상을 막기 위하여 event listener를 등록했으면 컴포넌트가 사라질 때는 event listener를 지워줘야 함.
컴포넌트가 사라지는 것을 뜻하는 라이프 사이클 메소드 componentWillUnmount에 removeEventListener를 추가해줌.
들어가는 인자는 addEventListener와 동일함.
- 그렇다면 함수형 컴포넌트에서는 이걸 어떻게 처리할까?
useEffect()라는 react hook을 사용.
- useEffect() :
라이프 사이클 함수 중 componentDidMount, componentDidUpdate, componentWillUnmount를
합쳐준 것이라고 보면 됨.
useEffect(( ) => { }, [ ]);
컴포넌트가 렌더링이 되면 화살표 함수가 실행됨.
그런데, 이 실행에는 조건이 있음.
- 첫 번째 실행은 무조건 일어남.(맨 처음 컴포넌트를 그릴 때 => 첫 렌더링이 일어날 때)
- 두 번째 실행부터는 화살표 함수를 무조건 실행하는 것이 아니라,
[ ](dependency Array => 의존성 배열)에 들어가 있는 요소를 확인함.
요소가 바뀐 게 있는지 확인하고, 바뀐게 있을 때만 화살표 함수를 실행함.
1. dependency Array를 비워뒀다면 요소가 바뀔 일이 평생 없으므로 componentDidMount처럼 동작.
(처음 한 번 실행하고 다시는 실행 X)
2. 그런데 만약,
dependency Array 안에 a라는 값이 있고, 버튼을 누를 때마다 a라는 값이 변한다면(a가 1에서 시작하여 계속 1씩 추가)
이럴 경우 화살표 함수가 다시 실행됨. =>componentDidUpdate랑 비슷한 동작을 함.
3. componentWillUnmount랑 비슷하게 동작하는 부분이 useEffect의 return 부분.
(useEffect는 함수이므로 return 값을 줄 수 있음)
화면이 사라질 때 동작하는 것을 return 부분에 넣어주면 됨.
useEffect(() => {
// 여기가 rendering 때 실행될 구문이 들어가는 부분.
// componentDidMount, componentDidUpdate일 때 동작하는 부분이 여기.
// do something ...
return () => {
// 여기가 clean up 부분.
// componentWillUnmount 때 동작하는 부분이 여기.
//do something ...
};
}, []);
Dom이 있을 때 addEventListener을 해줄 수 있으므로
렌더링이 끝나고 컴포넌트가 실제 Dom에 올라간 후인 componentDidMount 메소드에
addEventListener 코드를 작성해줘야 함.
아, 그전에 함수형 컴포넌트에서도 어떤 행동(이벤트 발생) 뒤에 실행할 함수를 먼저 만들어줌.
//Text.js ...
const hoverEvent = (e) => {
// 콘솔로 이 이벤트가 누구에게서 일어났는 지 확인할 수 있음.
console.log(e.target);
// ref랑 같은 녀석인 지 확인.
console.log(text.current);
text.current.style.background = "yellow";
};
return ...
이제 addEventListener()를 이용해서 이벤트를 등록.
//Text.js
useEffect(() => {
// 여기가 rendering 때 실행될 구문이 들어가는 부분.
// componentDidMount, componentDidUpdate일 때 동작하는 부분이 여기.
text.current.addEventListener("mouseover", hoverEvent);
return () => {
// 여기가 clean up 부분.
// componentWillUnmount 때 동작하는 부분이 여기.
//do something ... };
}, [text]);
event listener은 꼭 컴포넌트가 사라지면 지워줘야 함.
useEffect에서 clean up은 return 구문을 이용.
//Text.js
useEffect(() => {
// 여기가 rendering 때 실행될 구문이 들어가는 부분.
// componentDidMount, componentDidUpdate일 때 동작하는 부분이 여기.
text.current.addEventListener("mouseover", hoverEvent);
return () => {
// 여기가 clean up 부분.
// componentWillUnmount 때 동작하는 부분이 여기.
text.current.removeEventListener("mouseover", hoverEvent);
}, [text]);
- 잠깐, 여기서 하나 깨달은 사실.
react hook들은 React.다음에 넣어줘도 되고 (ex : React.useRef()) 혼자 사용해도 됨.(useRef())
but, react hook을 혼자 사용하려면 무조건 import가 필요함.
3-2. react-router-dom
- SPA란? : Single Page Application
서버에서 주는 html이 1개 뿐인 어플리케이션.
전통적인 웹사이트는 페이지를 이동할 때마다 서버에서 html, css, js(정적자원)를 내려준다면.
SPA는 딱 한 번만(시작할 때) 정적자원을 받아옴.
- 왜 굳이 html을 하나만 줄까?
가장 큰 이유는 사용성 때문.
페이지를 이동할 때마다 서버에서 주는 html로 화면을 바꾸다보면 상태 유지가 어렵고
바뀌지 않는 부분까지 새로 불러오니까 비효율적임.
(ex. 블로그 같은 경우, 페이지마다 새로 html을 받아오면 바뀐 건 글 뿐인데 헤더와 카테고리까지 전부 다시 불러와야 함.)
- SPA를 사용할 때 단점?
.
'(심층)리액트' 카테고리의 다른 글
다시 시작하는 리액트 - 리액트 실무 기초 4-1 (2) | 2023.04.03 |
---|---|
다시 시작하는 리액트 - 리액트 실무 기초 3 Quiz (1) | 2023.03.30 |
다시 시작하는 리액트 - 리액트 실무 기초 2 과제 (0) | 2023.03.29 |
다시 시작하는 리액트 - 리액트 실무 기초 2 (0) | 2023.03.27 |
(심층)리액트트위터 클론코딩(with firebase) - 06 (0) | 2023.02.18 |
github : https://github.com/dnjfht
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!