작성
·
72
0
안녕하세요 메모 추가 및 제거UI 강의를 듣다가 조금 헷갈리는 부분이 있어 질문을 드립니다.
import { useEffect, useRef, useState } from 'react';
import { AiOutlineClose, AiOutlineCheck } from 'react-icons/ai';
const Note = ({ id, onRemoveNote }) => {
const colorOptions = [
'bg-yellow-300',
'bg-pink-300',
'bg-blue-300',
'bg-green-300',
];
const [isEditing, setIsEditing] = useState(false);
const textareaRef = useRef(null);
const [content, setContent] = useState('');
useEffect(() => {
if (textareaRef.current) {
textareaRef.current.style.height =
textareaRef.current.scrollHeight + 'px';
}
}, [content]);
return (
<div
className={`p-4 bg-yellow-300 relative max-h-[32rem] overflow-hidden`}
onClick={() => setIsEditing(true)}
>
<div className="absolute top-2 right-2">
{isEditing ? (
<button
aria-label="Check Note"
className="text-gray-700"
onClick={e => {
e.stopPropagation();
setIsEditing(false);
}}
>
<AiOutlineCheck size={20} />
</button>
) : (
<button
aria-label="Close Note"
className="text-gray-700"
onClick={() => onRemoveNote(id)}
>
<AiOutlineClose size={20} />
</button>
)}
</div>
<textarea
ref={textareaRef}
value={content}
onChange={e => setContent(e.target.value)}
className={`w-full h-full bg-transparent resize-none border-none focus:outline-none text-gray-900 overflow-hidden`}
aria-label="Edit Note"
placeholder="메모를 작성하세요."
style={{ height: 'auto', minHeight: '8rem' }}
readOnly={!isEditing}
/>
{isEditing && (
<div className="flex space-x-2">
{colorOptions.map((option, index) => (
<button
key={index}
className={`w-6 h-6 rounded-full cursor-pointer outline outline-gray-50 ${option}`}
aria-label={`Change color to ${option}`}
/>
))}
</div>
)}
</div>
);
};
export default Note;
이 코드에서
useEffect(() => {
if (textareaRef.current) {
textareaRef.current.style.height =
textareaRef.current.scrollHeight + 'px';
}
}, [content]);
이렇게 useEffect를 사용했는데 useEffect는 컴포넌트가 마운트 될 때 먼저 실행이 되고 또 의존성배열이 빈배열이면 한번만 실행이 된다로 알고 있습니다. 그럼 여기서는 빈 배열이 아닌 content가 있으니 메모장에 작성할 때마다 메모장을 늘어나게 하기 위해서 useEffect를 사용했다라고 이해하면 될까요?
답변 2
0
안녕하세요! 네, 맞습니다.
useEffect
훅의 의존성 배열에 content
가 있기 때문에:
컴포넌트가 최초 마운트될 때 실행됩니다.
content
상태가 변경될 때마다 다시 실행됩니다.
이 코드의 핵심 목적은 textarea의 높이를 동적으로 조절하는 것입니다. 사용자가 내용을 입력할수록 textarea가 자동으로 확장되어 모든 콘텐츠를 표시할 수 있게 합니다. 이것은 사용자 경험을 개선하는 좋은 기능입니다.
textareaRef.current.style.height = textareaRef.current.scrollHeight + 'px';
위 코드는 텍스트 영역의 실제 콘텐츠 높이(scrollHeight
)를 측정하여 요소의 높이를 그에 맞게 설정합니다.
만약 의존성 배열이 빈 배열([]
)이었다면, 이 효과는 컴포넌트가 마운트될 때 한 번만 실행되었을 것이고, 사용자가 입력할 때 textarea 높이가 업데이트되지 않았을 것입니다.
이 패턴은 React에서 "auto-growing textarea"를 구현하는 일반적인 방법입니다. 사용자가 메모를 작성할 때마다 content 상태가 변경되고, useEffect가 실행되어 textarea의 높이를 조정하게 됩니다.
0
안녕하세요, 인프런 AI 인턴입니다. 부드러운 족제비님.
현재 코드는 메모장에서 사용자의 입력에 따라 textarea
의 높이를 동적으로 조절하기 위한 것입니다. useEffect
는 특정 조건이 변경될 때마다 코드를 실행할 수 있도록 도와주며, 이 경우에는 content
의 변경을 감지하여 textarea
의 높이를 조정하고 있습니다.
useEffect
의 역할:
useEffect
는 의존성 배열(content
) 내부의 값이 변화할 때마다 실행됩니다. 지금 코드는 사용자가 textarea
에 글자를 입력할 때마다 useEffect
가 실행되어 textarea
의 높이를 조절합니다.content
가 업데이트되고, 이는 useEffect
를 통해 새 높이를 계산하여 textarea
에 반영됩니다.textareaRef
와 height 설정:
textareaRef.current.scrollHeight
는 현재 textarea
의 내부 높이, 즉 최신 콘텐츠에 필요한 높이를 가져옵니다.style.height
에 설정하여 textarea
가 내용물에 맞게 늘어납니다.이와 같은 동작을 통해 textarea
는 사용자 입력에 따라 자동으로 크기가 조절되며, 이를 통해 사용자의 입력 경험을 개선할 수 있습니다.
관련 질문을 참고하시면 더욱 도움이 되실 것 같습니다:
- auto-resizing textarea with react hooks
- Dynamically resize a textarea based on content length using React
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.