기본 스티커 메모를 아시나요?

기본스티커 메모

헤더 부분을 드래그하면 이동되는 것과 메모 입력하는 기능을 흉내내보았는데요.

제 사이트에는 딱 저 2가지 기능만 필요하여 저 부분만 작업했습니다! 

 

Memo.js

import React, { useCallback, useRef, useState } from 'react';
import styled from 'styled-components';

const Wrap = styled.div`
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 200px;
    background: yellow;
    border: 1px solid #c0c0a4;
    box-sizing: border-box;
`;
const Header = styled.div`
    padding: 5px;
    width: 100%;
    font-size: 14px;
    font-weight: 700;
    color: yellow;
    background: #c0c0a4;
    text-align: center;
`;
const Content = styled.div`
    padding: 5%;
    max-height: 300px;
    overflow-y: auto;

    textarea {
        padding: 5%;
        width: 100%;
        min-height: 150px;
        box-sizing: border-box;
        background: none;
        outline: none;
        border: none;
    }
`;

const Memo = () => {
    const [memoText, setMemoText] = useState('');
    const wrapRef = useRef(null);
    const headerRef = useRef(null);
    let lastX = 0;
    let lastY = 0;
    let startX = 0;
    let startY = 0;

    const onFocusout = useCallback(({ target }) => {
        setMemoText(target.value);
    }, [memoText]);

    const onMove = useCallback((e) => {
        e.preventDefault(); 
        lastX = startX - e.clientX;
        lastY = startY - e.clientY;

        startX = e.clientX;
        startY = e.clientY;

        wrapRef.current.style.top = `${wrapRef.current.offsetTop - lastY}px`;
        wrapRef.current.style.left = `${wrapRef.current.offsetLeft - lastX}px`;
    }, []);

    const removeEvent = useCallback(() => {
        document.removeEventListener('mouseup', removeEvent);
        document.removeEventListener('mousemove', onMove);
    }, []);

    const onMouseDown = useCallback((e) => {
        e.preventDefault(); 
        startX = e.clientX;
        startY = e.clientY;

        document.addEventListener('mouseup', removeEvent);
        document.addEventListener('mousemove', onMove);
    }, []);

    return (
        <Wrap ref={wrapRef}>
            <Header 
                ref={headerRef}
                onMouseDown={onMouseDown}
            >
                Memo
            </Header>
            <Content>
                <textarea 
                    placeholder="메모를 입력해주세요..."
                    onBlur={onFocusout}    
                ></textarea>
            </Content>
        </Wrap>
    );
};

export default Memo;

포커스가 빠져나갈때 value값을 저장하도록 해두었습니다.

 

아! 코드는 js에서 사용하던 그대로 사용했으며.. ↓

okayoon.tistory.com/entry/%EB%A7%88%EC%9A%B0%EC%8A%A4%EB%A1%9C-%EC%B0%BD%EC%9D%84-%EC%9B%80%EC%A7%81%EC%97%AC%EB%B3%B4%EC%9E%90?category=835827

 

ref를 통해 style 값을 넣는 부분을 안하고 싶지만..

useState를 사용할 경우 안되더라구요. 비동기여서 그런듯한데....

동기로 잘 사용할 방법을 찾으면 해결 가능할 것 같은데....

velog.io/@aerirang647/32setState-%EB%B9%84%EB%8F%99%EA%B8%B0

 

[+32]setState -> 비동기

동기와 비동기동기: 코드 한 줄 한 줄 끝날 때까지 기다렸다가 다음줄로 넘어가는 성질.ex. forEach비동기: 코드 한 줄이 하고 있는 일이 끝나지 않았는데 일을 시켜놓고 내려가다가 일이 끝났다는

velog.io

여튼.. 그래서 그냥 ref를 통해 style을 수정해주고있습니다.

더 좋은 방법이 있을 것 같은데 아직 찾지를 못해서...ㅠ

쪼랩에게 좋은 의견이 있으면 말해주심 감사하겠습니다.

 

완성된 모양과 동작입니다.

메모 완성!

 

+ Recent posts