728x90
1. Done
Reference
코딩일레븐 님의 몇 줄로 끝내는 인터랙티브 웹 개발 노하우 [초급편] 강의를 수강하고 학습 내용을 정리합니다.
개념 설명
mousemove DOM 이벤트로 마우스의 수평(X), 수직(Y) 좌표를 clientX , clientY 로 받을 수 있다.
이 값으로 css의 transform 속성을 사용해 translate 해줄 px 값으로 사용한다.
리액트 버젼 코드
- 강사님 코드
- useState
- x축과 y축 값을 프로퍼티로 가진 객체를 초기값 0, 0으로 state 초기값 지정
- useEffect
- clientX, Y 값으로 setState 함수를 변수화하고 mousemove 이벤트에 addEventListener 콜백함수로 사용.
- 리턴값으로 클린업하는 함수에 removeEventListener의 콜백으로 윗 단계에서 변수화한 함수 사용.
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 }); useEffect(() => { const positionSet = (e) => setMousePosition({ x: e.clientX, y: e.clientY }); window.addEventListener("mousemove", positionSet); return () => { window.removeEventListener("mousemove", positionSet); }; }, []); return ( <> <p> x: {mousePosition.x} y: {mousePosition.y} </p> </> );
- useState
[디버깅] Over 200 classes were generated for component styled.div
warning 메세지:
Over 200 classes were generated for component styled.section.
Consider using the attrs method,
together with a style object for frequently changed styles.
x축, y축 값의 state를 props로 받아서 translate의 px값으로 사용하니 마우스 위치 이동시마다 위 컴포넌트가 재렌더링이 일어났다. attrs를 사용하는 방식으로 바꿔보았으나 계속 문제가 지속되어 transform 속성만 인라인 스타일링으로 따로 빼두니 해당 워닝은 해결되었다.
문제 코드
const CursorDiv = styled.div`
position: absolute;
width: 100px;
height: 100px;
background: linear-gradient(to left, skyblue, blue);
border-radius: 70%;
top: 0;
left: 0;
transform: translate(${({ position }) => `${position.x}px, ${position.y}px`});
`;
해결: 동적 스타일링하는 속성만 인라인 스타일로 분리.
- 스타일드 컴포넌트는 정적이거나 변화가 많지 않은 스타일이 적용되는 컴포넌트에만 사용해야 한다.
- 애니메이션 처럼 빈번히 변화하는 스타일에는 인라인 스타일을 사용해라.
<CursorDiv
style={{
transform: `translate(${cursorPosition.x}px, ${cursorPosition.y}px)`,
}}
/>
Reference
내 코드 - jsx
import React, { useState } from 'react';
import GlobalStyle from './GlobalStyle';
import styled from 'styled-components';
function App() {
const [cursorPosition, setCursorPosition] = useState({
x: 0,
y: 0,
});
const positionSetter = e => {
return setCursorPosition({
x: e.clientX,
y: e.clientY,
});
};
return (
<>
<GlobalStyle />
<Main onMouseMove={positionSetter}>
<H1>
x: {cursorPosition.x} y: {cursorPosition.y}
</H1>
<CursorDiv
style={{
transform: `translate(${cursorPosition.x}px, ${cursorPosition.y}px)`,
}}
/>
</Main>
</>
);
}
export default App;
내 코드 - styled-components
const Main = styled.main`
width: 100vw;
height: 100vh;
`;
const H1 = styled.h1`
color: #ffffff;
`;
const CursorDiv = styled.div`
position: absolute;
width: 100px;
height: 100px;
background: linear-gradient(to left, skyblue, blue);
border-radius: 70%;
top: 0;
left: 0;
`;
바닐라JS 버젼 코드
window.onload()
html 문서가 다 준비된 후에 자바스크립트 코드가 실행되도록 지시하는 함수. 리액트에서는 useEffect 훅을 사용하면 된다.
script.js
window.onload = () => {
const h1 = document.getElementsByTagName('h1')[0];
// const cursor_item = document.querySelector('cursor_item');
const cursor_item = document.getElementsByClassName('cursor_item')[0];
const mouseFunc = e => {
h1.innerHTML = `clientX: ${e.clientX} clientY: ${e.clientY}`;
cursor_item.style.transform =
'translate(' + e.clientX + 'px,' + e.clientY + 'px)';
// translate(635px,286px)
};
window.addEventListener('mousemove', mouseFunc, false);
};
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./styles.css" />
<script src="./script.js" defer></script>
</head>
<body>
<h1>테스트</h1>
<div class="cursor_item"></div>
</body>
</html>
style.css
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
position: relative;
background-color: #000000;
}
h1 {
color: #ffffff;
}
.cursor_item {
position: absolute;
width: 100px;
height: 100px;
background-color: red;
top: 0;
left: 0;
}
728x90
'기록 > Today I learned' 카테고리의 다른 글
22.11.11 금 TIL (0) | 2022.11.12 |
---|---|
22.11.10 목 TIL (0) | 2022.11.10 |
22.10.27 TIL - 포폴앱 타입스크립트 마이그레이션 (0) | 2022.10.29 |
22.10.26 TIL (0) | 2022.10.26 |
22.10.25 TIL (0) | 2022.10.25 |