简体   繁体   English

根据文本内容设置textarea的高度

[英]Set height of textarea based on text content

I'm using this example to set the height of the textarea.我正在使用这个例子来设置文本区域的高度。

but the size of the textarea is not set automatically if the textarea has a value.但是如果 textarea 有一个值,则不会自动设置 textarea 的大小。

https://codesandbox.io/s/autosize-textarea-forked-wdowvr?file=/src/App.tsx https://codesandbox.io/s/autosize-textarea-forked-wdowvr?file=/src/App.tsx

import { useRef, useState } from "react";

import "./styles.css";

export default function App() {
  const [value, setValue] = useState("");
  const textAreaRef = useRef<HTMLTextAreaElement>(null);

  const handleChange = (evt) => {
    const val = evt.target?.value;

    setValue(val);
  };

  return (
    <div className="App">
      <label htmlFor="review-text">Review:</label>
      <textarea
        id="review-text"
        onChange={handleChange}
        onInput={(e: React.FormEvent<HTMLTextAreaElement>) => {
          e.currentTarget.style.height = e.currentTarget.scrollHeight + "px";
        }}
        ref={textAreaRef}
        rows={1}
        value={value}
      />
    </div>
  );
}

for example例如

how can i fix this issue?我该如何解决这个问题?

You can use the following snippets to adjust the height on loading the component.您可以使用以下代码片段来调整加载组件时的高度。

Just for demo purposes:仅用于演示目的:

const [value, setValue] = useState(
  "already has a value with\nmore text\nand even more"
);
const textAreaRef = useRef<HTMLTextAreaElement>(null);

You can access the ref once it is set.您可以在设置 ref 后访问它。 useEffect will do the trick here. useEffect将在这里发挥作用。

useEffect(() => {
  if (textAreaRef && textAreaRef.current) {
    textAreaRef.current.style.height = textAreaRef.current.scrollHeight + 'px';
  }
}, []);

https://codesandbox.io/s/autosize-textarea-forked-symr7p?file=/src/App.tsx https://codesandbox.io/s/autosize-textarea-forked-symr7p?file=/src/App.tsx

You also need to set the height once the DOM is mounted.安装DOM后,您还需要设置高度。 This way it can respond to whatever value is in there before any user input.这样它就可以在任何用户输入之前响应其中的任何值。
I did this with the useEffect hook.我用useEffect钩子做了这个。 (Don't forget to import it from react ). (不要忘记从react import它)。

I also tweaked the method of changing the height a bit, because it wasn't working properly.我还稍微调整了改变高度的方法,因为它不能正常工作。

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

import "./styles.css";

export default function App() {
  const [value, setValue] = useState("");
  const textAreaRef = useRef<HTMLTextAreaElement>(null);

  const handleChange = (evt) => {
    const val = evt.target?.value;

    setValue(val);
  };

  const resizeTextarea = (t: HTMLTextAreaElement) => {
    t.style.height = "auto";
    const p = parseFloat(window.getComputedStyle(t, null).getPropertyValue("padding-top")) 
            + parseFloat(window.getComputedStyle(t, null).getPropertyValue("padding-bottom"));
    t.style.height = t.scrollHeight - p + "px";
  }

  const handleInput = (e: React.FormEvent<HTMLTextAreaElement>) => {
    resizeTextarea(e.currentTarget);
  }

  useEffect(() => {
    const t = textAreaRef.current;
    if (t != null) {
      t.style.overflowY = 'hidden';
      resizeTextarea(t);
    }
 },[]);

  return (
    <div className="App">
      <label htmlFor="review-text">Review:</label>
      <textarea
        id="review-text"
        onChange={handleChange}
        onInput={handleInput}
        ref={textAreaRef}
        rows={1}
        value={value}
      />
    </div>
  );
}

https://codesandbox.io/s/autosize-textarea-forked-s39ur2?file=/src/App.tsx:0-1172 https://codesandbox.io/s/autosize-textarea-forked-s39ur2?file=/src/App.tsx:0-1172

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM