// 길이 조정 함수
export const onTextAreaResizeHeight = (
textAreaRef: React.RefObject<HTMLTextAreaElement>
) => {
if (textAreaRef.current != null) {
textAreaRef.current.style.height = "auto";
return (textAreaRef.current.style.height =
textAreaRef?.current?.scrollHeight + "px");
}
return null;
};
위 함수는 매개변수로 textAreaRef
라는 것을 받는다.
해당 매개변수는 useRef이면서<HTMLTextAreaElement>
라는 타입이어야 한다.
왜냐하면 react는 직접적으로 DOM을 조작하는 방향을 추구하지 않기 때문에 useRef로 <textarea>
의 value를 추출하기 위함이다.
"use client";
// PostForm.tsx
import {
ChangeEventHandler,
FormEvent,
FormEventHandler,
useRef,
useState,
} from "react";
import style from "./postForm.module.css";
import { useSession } from "next-auth/react";
import { Session } from "@auth/core/types";
import { onTextAreaResizeHeight } from "../../_lib/onTextAreaResizeHeight";
type Props = {
me: Session | null;
};
export default function PostForm({ me }: Props) {
const [content, setContent] = useState<string>("");
const imageRef = useRef<HTMLInputElement>(null);
const textAreaRef = useRef<HTMLTextAreaElement>(null);
// const { data: me } = useSession(); // 클라이언트에서만 사용가능. 유저 정보를 불러온다.
const onChange: ChangeEventHandler<HTMLTextAreaElement> = (e) => {
setContent(e.target.value);
};
const onSubmit: FormEventHandler = (e: FormEvent<Element>) => {
e.preventDefault();
};
const onClickButton = () => {
imageRef.current?.click();
};
return (
<form className={style.postForm} onSubmit={onSubmit}>
<div className={style.postUserSection}>
<div className={style.postUserImage}>
<img src={me?.user?.image as string} alt={me?.user?.id as string} />
</div>
</div>
<div className={style.postInputSection}>
<textarea
value={content}
onChange={(e) => {
onChange(e);
onTextAreaResizeHeight(textAreaRef);
}}
placeholder="무슨 일이 일어나고 있나요?"
ref={textAreaRef}
/>
<div className={style.postButtonSection}>
<div className={style.footerButtons}>
<div className={style.footerButtonLeft}>
<input
type="file"
name="imageFiles"
multiple
hidden
ref={imageRef}
/>
<button
title="이미지 추가 버튼"
className={style.uploadButton}
type="button"
onClick={onClickButton}>
<svg width={24} viewBox="0 0 24 24" aria-hidden="true">
<g>
<path d="M3 5.5C3 4.119 4.119 3 5.5 3h13C19.881 3 21 4.119 21 5.5v13c0 1.381-1.119 2.5-2.5 2.5h-13C4.119 21 3 19.881 3 18.5v-13zM5.5 5c-.276 0-.5.224-.5.5v9.086l3-3 3 3 5-5 3 3V5.5c0-.276-.224-.5-.5-.5h-13zM19 15.414l-3-3-5 5-3-3-3 3V18.5c0 .276.224.5.5.5h13c.276 0 .5-.224.5-.5v-3.086zM9.75 7C8.784 7 8 7.784 8 8.75s.784 1.75 1.75 1.75 1.75-.784 1.75-1.75S10.716 7 9.75 7z"></path>
</g>
</svg>
</button>
</div>
<button className={style.actionButton} disabled={!content}>
게시하기
</button>
</div>
</div>
</div>
</form>
);
}