<textarea>
O componente nativo do navegador <textarea>
permite renderizar uma entrada de texto de várias linhas.
<textarea />
Referência
<textarea>
Para exibir uma área de texto, renderize o componente nativo do navegador <textarea>
.
<textarea name="postContent" />
Props
O <textarea>
suporta todas as props comuns de elementos.
Você pode transformar uma área de texto em controlada passando uma prop value
:
value
: Uma string. Controla o texto dentro da área de texto.
Quando você passa value
, você também deve passar um manipulador onChange
que atualiza o valor passado.
Se o seu <textarea>
não for controlado, você pode passar a prop defaultValue
em vez disso:
defaultValue
: Uma string. Especifica o valor inicial para uma área de texto.
Essas props do <textarea>
são relevantes tanto para áreas de texto não controladas quanto para áreas de texto controladas:
autoComplete
: Ou'on'
ou'off'
. Especifica o comportamento de preenchimento automático.autoFocus
: Um booleano. Setrue
, o React irá focar no elemento ao montar.children
:<textarea>
não aceita filhos. Para definir o valor inicial, usedefaultValue
.cols
: Um número. Especifica a largura padrão em larguras médias de caracteres. O padrão é20
.disabled
: Um booleano. Setrue
, a entrada não será interativa e aparecerá esmaecida.form
: Uma string. Especifica oid
do<form>
ao qual esta entrada pertence. Se omitido, é o formulário pai mais próximo.maxLength
: Um número. Especifica o comprimento máximo do texto.minLength
: Um número. Especifica o comprimento mínimo do texto.name
: Uma string. Especifica o nome para esta entrada que é enviada com o formulário.onChange
: Uma função deEvent
handler. Necessário para áreas de texto controladas. Dispara imediatamente quando o valor da entrada é alterado pelo usuário (por exemplo, ele dispara a cada pressionamento de tecla). Comporta-se como o eventoinput
do navegador.onChangeCapture
: Uma versão deonChange
que dispara na fase de captura.onInput
: Uma função deEvent
handler. Dispara imediatamente quando o valor é alterado pelo usuário. Por razões históricas, no React é idiomático usaronChange
em vez disso, que funciona de forma semelhante.onInputCapture
: Uma versão deonInput
que dispara na fase de captura.onInvalid
: Uma função deEvent
handler. Dispara se uma entrada falha na validação no envio do formulário. Ao contrário do eventoinvalid
nativo, o eventoonInvalid
do React propaga.onInvalidCapture
: Uma versão deonInvalid
que dispara na fase de captura.onSelect
: Uma função deEvent
handler. Dispara após a alteração da seleção dentro do<textarea>
. O React estende o eventoonSelect
para também disparar para seleção vazia e em edições (o que pode afetar a seleção).onSelectCapture
: Uma versão deonSelect
que dispara na fase de captura.placeholder
: Uma string. Exibido em uma cor esmaecida quando o valor da área de texto está vazio.readOnly
: Um booleano. Setrue
, a área de texto não é editável pelo usuário.required
: Um booleano. Setrue
, o valor deve ser fornecido para que o formulário seja enviado.rows
: Um número. Especifica a altura padrão em alturas médias de caracteres. O padrão é2
.wrap
: Ou'hard'
,'soft'
, ou'off'
. Especifica como o texto deve ser quebrado ao enviar um formulário.
Caveats
- Passar filhos como
<textarea>something</textarea>
não é permitido. UsedefaultValue
para conteúdo inicial. - Se uma área de texto receber uma prop string
value
, ela será tratada como controlada. - Uma área de texto não pode ser controlada e não controlada ao mesmo tempo.
- Uma área de texto não pode alternar entre ser controlada ou não controlada durante sua vida útil.
- Toda área de texto controlada precisa de um manipulador de eventos
onChange
que atualize de forma síncrona seu valor de backup.
Uso
Exibindo uma área de texto
Renderize <textarea>
para exibir uma área de texto. Você pode especificar seu tamanho padrão com os atributos rows
e cols
, mas, por padrão, o usuário poderá redimensioná-la. Para desativar o redimensionamento, você pode especificar resize: none
no CSS.
export default function NewPost() { return ( <label> Escreva sua postagem: <textarea name="postContent" rows={4} cols={40} /> </label> ); }
Fornecendo um rótulo para uma área de texto
Normalmente, você colocará cada <textarea>
dentro de uma tag <label>
. Isso informa ao navegador que este rótulo está associado àquela área de texto. Quando o usuário clica no rótulo, o navegador vai focar na área de texto. Também é essencial para acessibilidade: um leitor de tela anunciará a legenda do rótulo quando o usuário focar na área de texto.
Se você não puder aninhar <textarea>
em um <label>
, associe-os passando o mesmo ID para <textarea id>
e <label htmlFor>
. Para evitar conflitos entre instâncias de um componente, gere tal ID com useId
.
import { useId } from 'react'; export default function Form() { const postTextAreaId = useId(); return ( <> <label htmlFor={postTextAreaId}> Escreva sua postagem: </label> <textarea id={postTextAreaId} name="postContent" rows={4} cols={40} /> </> ); }
Fornecendo um valor inicial para uma área de texto
Você pode opcionalmente especificar o valor inicial para a área de texto. Passe-o como a string defaultValue
.
export default function EditPost() { return ( <label> Edite sua postagem: <textarea name="postContent" defaultValue="Eu realmente gostei de andar de bicicleta ontem!" rows={4} cols={40} /> </label> ); }
Lendo o valor da área de texto ao enviar um formulário
Adicione um <form>
em torno de sua textarea com um <button type="submit">
dentro. Ele chamará seu manipulador de eventos <form onSubmit>
. Por padrão, o navegador enviará os dados do formulário para o URL atual e atualizará a página. Você pode substituir esse comportamento chamando e.preventDefault()
. Leia os dados do formulário com new FormData(e.target)
.
export default function EditPost() { function handleSubmit(e) { // Evite que o navegador recarregue a página e.preventDefault(); // Leia os dados do formulário const form = e.target; const formData = new FormData(form); // Você pode passar formData como um corpo de busca diretamente: fetch('/some-api', { method: form.method, body: formData }); // Ou você pode trabalhar com ele como um objeto simples: const formJson = Object.fromEntries(formData.entries()); console.log(formJson); } return ( <form method="post" onSubmit={handleSubmit}> <label> Título da postagem: <input name="postTitle" defaultValue="Biking" /> </label> <label> Edite sua postagem: <textarea name="postContent" defaultValue="Eu realmente gostei de andar de bicicleta ontem!" rows={4} cols={40} /> </label> <hr /> <button type="reset">Redefinir edições</button> <button type="submit">Salvar postagem</button> </form> ); }
Controlando uma área de texto com uma variável de estado
Uma área de texto como <textarea />
é não controlada. Mesmo se você passar um valor inicial como <textarea defaultValue="Text initial" />
, seu JSX especifica apenas o valor inicial, não o valor agora.
Para renderizar uma área de texto controlada, passe a prop value
para ela. React irá forçar a área de texto a sempre ter o value
que você passou. Normalmente, você controlará uma área de texto declarando uma variável de estado:
function NewPost() {
const [postContent, setPostContent] = useState(''); // Declare uma variável de estado...
// ...
return (
<textarea
value={postContent} // ...force o valor da entrada para corresponder à variável de estado...
onChange={e => setPostContent(e.target.value)} // ... e atualize a variável de estado em qualquer edição!
/>
);
}
Isso é útil se você deseja re-renderizar alguma parte da UI em resposta a cada pressionamento de tecla.
{ "dependencies": { "react": "latest", "react-dom": "latest", "react-scripts": "latest", "remarkable": "2.0.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" }, "devDependencies": {} }
Solução de problemas
Minha área de texto não atualiza quando digito nela
Se você renderizar uma área de texto com value
mas sem onChange
, você verá um erro no console:
// 🔴 Bug: área de texto controlada sem manipulador onChange
<textarea value={something} />
value
para um campo de formulário sem um manipulador onChange
. Isso renderizará um campo somente leitura. Se o campo deve ser mutável, use defaultValue
. Caso contrário, defina onChange
ou readOnly
.Como a mensagem de erro sugere, se você só quisesse especificar o valor inicial, passe defaultValue
em vez disso:
// ✅ Bom: área de texto não controlada com um valor inicial
<textarea defaultValue={something} />
Se você quiser controlar esta área de texto com uma variável de estado, especifique um manipulador de onChange
:
// ✅ Bom: área de texto controlada com onChange
<textarea value={something} onChange={e => setSomething(e.target.value)} />
Se o valor for intencionalmente somente leitura, adicione uma prop readOnly
para suprimir o erro:
// ✅ Bom: área de texto controlada somente leitura sem alteração
<textarea value={something} readOnly={true} />
Meu cursor da área de texto salta para o início a cada pressionamento de tecla
Se você controla uma área de texto, você deve atualizar sua variável de estado para o valor da área de texto do DOM durante onChange
.
Você não pode atualizá-lo para algo diferente de e.target.value
:
function handleChange(e) {
// 🔴 Bug: atualizando uma entrada para algo diferente de e.target.value
setFirstName(e.target.value.toUpperCase());
}
Você também não pode atualizá-lo de forma assíncrona:
function handleChange(e) {
// 🔴 Bug: atualizando uma entrada de forma assíncrona
setTimeout(() => {
setFirstName(e.target.value);
}, 100);
}
Para corrigir seu código, atualize-o de forma síncrona para e.target.value
:
function handleChange(e) {
// ✅ Atualizando uma entrada controlada para e.target.value de forma síncrona
setFirstName(e.target.value);
}
Se isso não resolver o problema, é possível que a área de texto seja removida e readicionada do DOM a cada pressionamento de tecla. Isso pode acontecer se você estiver acidentalmente redefinindo o estado a cada re-renderização. Por exemplo, isso pode acontecer se a área de texto ou um de seus pais sempre receber um atributo key
diferente, ou se você aninhar definições de componentes (o que não é permitido no React e faz com que o componente “interno” seja remontado a cada renderização).
Estou recebendo um erro: “Um componente está mudando uma entrada não controlada para ser controlada”
Se você fornecer um value
para o componente, ele deverá permanecer uma string durante toda a sua vida útil.
Você não pode passar value={undefined}
primeiro e depois passar value="alguma string"
porque o React não saberá se você deseja que o componente seja não controlado ou controlado. Um componente controlado sempre deve receber um value
string, não null
ou undefined
.
Se o seu value
está vindo de um API ou uma variável de estado, ele pode ser inicializado para null
ou undefined
. Nesse caso, ou defina-o para uma string vazia (''
) inicialmente, ou passe value={someValue ?? ''}
para garantir que value
seja uma string.