textarea가 입력된 텍스트가 길어지면 세로 스크롤이 생기는데,
화면 전체에도 스크롤이 2중으로 생겨서 사용성이 좋지 못했다.
textarea의 텍스트가 길어지면 스크롤이 생기는 것이 아닌 heigth가 늘어나도록 수정했다
→ 키 입력 이벤트가 발생할 때마다 textarea의 height를 scrollHeight로 할당해주는 방법
하지만 수정할 때의 경우 처음부터 텍스트가 입력돼야하기 때문에 초기 height값이 scrollHeight가 되어야 했다.
useRef는 돔이 렌더링 되기 전에는 초기 값이 들어오고, 렌더링 후에 지정한 돔과 연결되기 때문에, useEffect의 의존성으로 textRef.current를 걸고, 상태를 textarea의 scrollHeight를 바꿔준 후 상태를 textarea의 height로 설정해주었다.
(textRef에 돔이 연결되고 나서 지정한 로직이 자동으로 실행되도록)
const ArticleEditor = ({ value, onChange, disabled, title, ...props }) => {
const [textAreaHeight, setTextAreaHeight] = useState('auto');
const textRef = React.createRef();
const handleInputChange = e => {
onChange && onChange(e);
};
useEffect(() => {
setTextAreaHeight(textRef.current.scrollHeight);
}, [textRef.current]);
const autoResizeTextarea = () => {
const textarea = textRef.current;
if (textarea) {
textarea.style.height = 'auto';
const height = textarea.scrollHeight;
textarea.style.height = `${height + 24}px`;
}
};
return (
<StyledSection {...props}>
<StyledInput
width="100%"
height="2rem"
name="title"
value={value.title || ''}
onChange={handleInputChange}
disabled={disabled && disabled}
placeholder="제목을 입력해주세요"
maxlength="300"
/>
<Line />
<StyledTextArea
textRef={textRef}
width="100%"
height={`${textAreaHeight}px`}
name="contents"
value={value.contents || ''}
onInput={handleInputChange}
disabled={disabled && disabled}
placeholder="내용을 입력해주세요"
maxlength="5000"
onKeyDown={autoResizeTextarea}
onKeyUp={autoResizeTextarea}
/>
</StyledSection>
);
};
텍스트를 치면서 height가 늘어날 때 전체 페이지의 scroll이 자동으로 맨 밑으로 내려가는 처리를 시도했는데, onChange이벤트가 발생할 때마다 리렌더링이 일어나서 스크롤이 위로 자꾸 당겨지는 문제가 있었다.