1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

文字数に合わせてtextareaの高さを自動伸縮させる(useRef + useEffect)

1
Posted at

React標準の useRef と useEffect で実装する。

1. デフォルトのtextarea

HTMLの<textarea>は、デフォルトでは枠のサイズが固定されていて、あふれた文字は内部スクロールで表示される仕様になっている。

そのため、

  1. 文字全体の実際の高さ(見えていないスクロール領域を含む高さ)の取得
  2. その高さをtextarea自身のCSS(height)に直接適用する

JavaScriptには要素の中身の総高さを取得できる scrollHeight というプロパティを利用します。

2. useRef と useEffect の役割

  • useRef
    • 役割:React管理下の特定のHTML要素(今回は<textarea>)を直接捕まえるための「参照(ピン留め)」を作る
    • イメージ:対象のタグに目印のタグをつけておき、いつでもref.currentでそのDOM要素にアクセスできるようにする
  • useEffect
    • 役割:画面の描画後や特定の値(State)が変わったタイミングで処理を実行する
    • 今回の目的:「テキスト(入力内容)が1文字でも変わったら、高さを測り直して更新する」ために使う

3. 最小構成のコード例

import React, { useState, useRef, useEffect } from "react";

export default function AutoResizeTextarea() {
  const [text, setText] = useState("");
  // 1. textareaのDOMにアクセスするための参照を作成
  const textareaRef = useRef(null);

  // 2. textが更新されるたびに実行される処理
  useEffect(() => {
    const element = textareaRef.current;
    if (!element) return;

    // ① 一度高さをautoにリセットする
    element.style.height = "auto";

    // ② 中身の全体の高さ(scrollHeight)を取得し、heightにセットする
    element.style.height = `${element.scrollHeight}px`;
  }, [text]); // textが変更された時だけトリガー

  return (
    <textarea
      ref={textareaRef}
      value={text}
      onChange={(e) => setText(e.target.value)}
      rows={1} // 初期値は1行分に設定
      placeholder="メッセージを入力..."
      style={{
        width: "100%",
        resize: "none",     // ユーザーの手動リサイズつまみを消す
        overflow: "hidden", // スクロールバーを消す
        boxSizing: "border-box",
      }}
    />
  );
}

4. 補足

  • element.style.height = "auto" がないと、「文字を増やしたときは伸びるのに、BackSpaceで文字を消しても縮まない」となる。
    そのため、一度 auto で高さをリセットしてから scrollHeight で高さを計り直す
  • CSSの指定
    • resize: "none" : ユーザーが右下のつまみをドラッグして自由にサイズ変更できないようにする
    • overflow: "hidden" : 計算と再描画のわずかな隙間にスクロールバーがチラつくのを防ぐ
1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?