React

[TIL/React] 2023/08/21

event page ๊ด€๋ จ ๐ŸŸ  ์ •์œก๊ฐ์˜ event page๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•œ๋‹ค. ๋งˆ์šฐ์Šค๋ฅผ 'press'ํ•˜๊ณ (click๊ณผ ๊ตฌ๋ถ„ํ•  ๊ฒƒ) ์šฐ์ธก์—์„œ ์ขŒ์ธก์œผ๋กœ ๋„˜๊ธฐ๋ฉด, ์ง„ํ–‰์ค‘์ธ event๋“ค์ด oveflow๋˜๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. best practice๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐฉ์‹์„ ํƒํ–ˆ

2023๋…„ 8์›” 21์ผ2min read

event page ๊ด€๋ จ ๐ŸŸ 

์ •์œก๊ฐ์˜ event page๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•œ๋‹ค. ๋งˆ์šฐ์Šค๋ฅผ 'press'ํ•˜๊ณ (click๊ณผ ๊ตฌ๋ถ„ํ•  ๊ฒƒ) ์šฐ์ธก์—์„œ ์ขŒ์ธก์œผ๋กœ ๋„˜๊ธฐ๋ฉด, ์ง„ํ–‰์ค‘์ธ event๋“ค์ด oveflow๋˜๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. best practice๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐฉ์‹์„ ํƒํ–ˆ๋‹ค.

best practice ๐Ÿ”ต

code
import React, { useState } from "react";
import styled from "styled-components";

const CardContainer = styled.div`
  display: flex;
  overflow-x: scroll;
  width: 100%;
  height: 200px;
  background-color: #f0f0f0;
  cursor: grab;
`;

const Card = styled.div`
  flex: 0 0 200px;
  height: 100%;
  background-color: #fff;
  border: 1px solid #ccc;
  margin-right: 10px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 20px;
`;

const App = () => {
  const [isMousePressed, setIsMousePressed] = useState(false);
  const [containerScrollLeft, setContainerScrollLeft] = useState(0);
  const [startMouseX, setStartMouseX] = useState(0);

  const handleMousePress = (e) => {
    setIsMousePressed(true);
    setStartMouseX(e.pageX - e.currentTarget.offsetLeft);
    setContainerScrollLeft(e.currentTarget.scrollLeft);
  };

  const handleMouseMove = (e) => {
    if (!isMousePressed) return;
    e.preventDefault();
    const currentMouseX = e.pageX - e.currentTarget.offsetLeft;
    const mouseMovement = currentMouseX - startMouseX;
    console.log(mouseMovement);
    console.log("2", containerScrollLeft);
    e.currentTarget.scrollLeft = containerScrollLeft - mouseMovement;
  };

  const handleMouseRelease = () => {
    setIsMousePressed(false);
  };

  return (
    <CardContainer
      // ๋ˆ„๋ฅด๋Š” ์ˆœ๊ฐ„
      onMouseDown={handleMousePress}
      onMouseMove={handleMouseMove}
      onMouseUp={handleMouseRelease}
      onMouseLeave={handleMouseRelease}
    >
      {/* ์นด๋“œ ์ปดํฌ๋„ŒํŠธ๋“ค */}

      <Card>Card 1</Card>
      <Card>Card 2</Card>
      <Card>Card 3</Card>
      <Card>Card 4</Card>
      <Card>Card 5</Card>
      <Card>Card 1</Card>
      <Card>Card 2</Card>
      <Card>Card 3</Card>
      <Card>Card 4</Card>
      <Card>Card 5</Card>
    </CardContainer>
  );
};

export default App;

card container์— onMouseDown, onMouseMove, onMouseUp, onMouseLeave๊ฐ€ ์กด์žฌํ•œ๋‹ค.

onClick์€ 'ํด๋ฆญ'ํ•  ๋•Œ ํŠน์ • event ๊ฐ์ฒด๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์œ„ ์š”์†Œ๋“ค๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค.

onMouseDown๋Š” ๋งˆ์šฐ์Šค๋กœ pressํ•  ๋•Œ, onMouseMove๋Š” ๋งˆ์šฐ์Šค๋กœ ๋”์—์„œ ์›€์ง์ผ ๋•Œ, onMouseUp๋Š” ๋งˆ์šฐ์Šค๋ฅผ ๋—„ ๋•Œ, onMouseLeave๋Š” ํŠน์ • element์—์„œ ๋งˆ์šฐ์Šค๊ฐ€ ๋– ๋‚ฌ์„ ๋•Œ event ๊ฐ์ฒด๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

1. onMouseDown

onMouseDown์—๋Š” handleMousePress ํ•จ์ˆ˜๊ฐ€ ์ „๋‹ฌ๋œ๋‹ค. isMousePressed๋ผ๋Š” ์ƒํƒœ๋ฅผ true๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค. ์ด์–ด์„œ startMouseX๋ผ๋Š” ์ƒํƒœ๋ฅผ, 'press'ํ•˜๋Š” ์ˆœ๊ฐ„ page์˜ x์ขŒํ‘œ์—์„œ card container์˜ offsetLeft๋ฅผ ๋บ€ ๊ฐ’์œผ๋กœ updateํ•œ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ containerScrollLeft๋ผ๋Š” ์ƒํƒœ๋ฅผ e.currentTarget.scrollLeft๋กœ updateํ•œ๋‹ค

2. onMouseMove

pressํ•œ ์ƒํƒœ๋ผ๋ฉด if๋ฌธ์„ ํ†ต๊ณผํ•œ ๋’ค preventDefault ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค. ์ดํ›„ currentMouseX ์ƒ์ˆ˜์— page์˜ x์ขŒํ‘œ์—์„œ offsetLeft๋ฅผ ๋บ€ ๊ฐ’์„ ํ• ๋‹นํ•œ๋‹ค. ์›€์ง์ธ ์ดํ›„์˜ x์ขŒํ‘œ๋ฅผ ์˜๋ฏธํ•˜๊ธฐ์— startMouseX์˜ x์ขŒํ‘œ์™€๋Š” ๊ตฌ๋ถ„๋œ๋‹ค๋Š” ์ ์„ ์ธ์ง€ํ•ด์•ผ ํ•œ๋‹ค.

mouseMovement ์ƒ์ˆ˜๋Š” currrent page์˜ x์ขŒํ‘œ์—์„œ start page์˜ x์ขŒํ‘œ๋ฅผ ๋บ€ ๊ฐ’์ด ํ• ๋‹น๋œ๋‹ค.

preventDefault, currentMouseX ํ• ๋‹น, mouseMovement ํ• ๋‹น์ด ์ข…๋ฃŒ๋˜๋ฉด, ๋งˆ์ง€๋ง‰์œผ๋กœ e.currentTarget.scrollLeft ๊ฐ’์„ containerScrollLeft์—์„œ mouseMovement๋ฅผ ๋บ€ ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

3. onMouseUp, onMouseLeave

isMousePressed๋ฅผ false๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ธฐ๋Šฅ๋งŒ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

ํšŒ๊ณ  ๐Ÿ”ด

containerScrollLeft ๋ถ€๋ถ„์ด ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์•˜๋‹ค. ๋‚ด์ผ์€ containerScrollLeft๊นŒ์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ์ดํ•ดํ•ด์„œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๋Š” ๋ฐ ์„ฑ๊ณตํ•˜๊ธธ ๋ฐ”๋ž€๋‹ค. ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๊ณ  ์ž๋ ค๋‹ˆ๊นŒ ๊ต‰์žฅํžˆ ์ฐ์ฐํ•œ๋ฐ, ์ฒ˜์Œ ์‹œ๋„ํ•ด ๋ณด๋Š” ๊ฑฐ๋‹ˆ๊นŒ ์ฒซ ์ˆ ์— ๋ฐฐ๋ถ€๋ฅด๋ ค ์š•์‹ฌ๋‚ด์ง€ ๋ง์ž. ๋ฐ”๋ณด ๊ฐ์ž ์ฃผ์ œ์— ํ•œ ํ์— ์ดํ•ด๋˜๊ธธ ๋ฐ”๋ผ๋Š” ๊ฑด '์˜ค๋ฒ„'๋‹ค.

More to read

Amazon VPC

Amazon VPC Architecture ์ดํ•ดํ•˜๊ธฐ

์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ๊ธฐํšํ•˜๋ฉฐ, ๊ฐœ๋ฐœ์—์„œ ๋ฌด์—‡์„ ๊ฐ€์žฅ ๋จผ์ € ๊ณ ๋ฏผํ•ด์•ผ ํ•˜๋Š”์ง€ ๋‹ค์‹œ ๋Œ์•„๋ณด๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.ํ•œ๋•Œ๋Š” ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ๋ชจ๋“  ์„ค๊ณ„์˜ ์ถœ๋ฐœ์ ์ด๋ผ๊ณ  ๋ฏฟ์—ˆ์Šต๋‹ˆ๋‹ค. ์œ ์ €๊ฐ€ ๋ฌด์—‡์„ ๋ณด๊ณ , ์–ด๋–ค ํ๋ฆ„์—์„œ ๋จธ๋ฌด๋ฅด๊ณ  ์ดํƒˆํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ดํ•ด ์—†์ด ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ ๋‹ค๋Š” ๊ฑด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๊ธฐ

'์›์‚ฌ์ดํŠธ'

ํ”„๋ก ํŠธ์—”๋“œ ๊ด€์ ์œผ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ดํ•ดํ•˜๊ธฐ

์˜ค๋žœ๋งŒ์— ๋ฐฉ๋ฒ•๋ก ์— ๊ด€ํ•œ ๊ธ€์„ ์“ฐ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ตœ๊ทผ ์ƒํ™ฉ์€ ์ด๋ ‡์Šต๋‹ˆ๋‹ค. SSAFY์—์„œ๋Š” ํ•˜๋ฃจ์— ์—„์ฒญ๋‚œ ์–‘์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ๋“ค์„ ๊ณผ์ œ๋กœ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ ๊ณผ์ •์—์„œ, '๊ตฌํ˜„๋ ฅ'์ด ๋งค์šฐ ๋–จ์–ด์ง„๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์™„์ „ํžˆ ์–ด๋ ค์šด ๋ฌธ์ œ๋ผ๋ฉด '์•„์‰ฌ์›€'์ด๋ผ๋Š” ๊ฐ์ •์กฐ์ฐจ ๋А๋ผ์ง€

Subnet

VPC ์„ค๊ณ„์˜ ์‹œ์ž‘: IP์™€ Subnet

๋ฐ˜๋ณต๋˜๋Š” ๋ฃจํ‹ด ์†์—์„œ ์–ป์€ ์•ˆ์ •๊ฐ์„ ๋ฐœํŒ ์‚ผ์•„, ์ด์ œ๋Š” ๊ธฐ์ˆ ์  ์ŠคํŽ™ํŠธ๋Ÿผ์„ ๋„“ํžˆ๊ธฐ ์œ„ํ•œ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ์— ์ฐฉ์ˆ˜ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์˜ ๋ชฉํ‘œ๋Š” ๋‹จ์ˆœํ•œ ํฌํŠธํด๋ฆฌ์˜ค ๊ตฌ์ถ•์„ ๋„˜์–ด, ์‹ค์ œ ์„œ๋น„์Šค ์ˆ˜์ค€์˜ ๋ธ”๋กœ๊ทธ ์‹œ์Šคํ…œ ๊ตฌํ˜„๊ณผ ๋‹ค๊ตญ์–ด ์ฒ˜๋ฆฌ ์ ์šฉ ๋“ฑ ์‹ค๋ฌด์— ๊ฐ€๊นŒ์šด ์—ญ๋Ÿ‰์„ ํ•œ ๋‹จ๊ณ„