<textarea>
O componente <textarea>
embutido no navegador permite renderizar um campo de entrada de texto em várias linhas.
<textarea />
Referência
<textarea>
Para exibir uma área de texto, renderize o componente <textarea>
embutido no navegador.
<textarea name="postContent" />
Props
<textarea>
suporta todas as props de elementos comuns.
Você pode tornar uma área de texto controlada passando uma prop value
:
value
: Uma string. Controla o texto dentro da área de texto.
Quando você passa value
, também deve passar um manipulador onChange
que atualiza o valor passado.
Se a sua <textarea>
for não controlada, você pode passar a prop defaultValue
em vez disso:
defaultValue
: Uma string. Especifica o valor inicial para uma área de texto.
Estas props <textarea>
são relevantes tanto para áreas de texto controladas quanto não controladas:
autoComplete
: Pode ser'on'
ou'off'
. Especifica o comportamento de autocompletar.autoFocus
: Um booleano. Setrue
, o React focará o 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 médias larguras 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 desta entrada que será enviado com o formulário.onChange
: Uma funçãoEvent
handler. Necessária para áreas de texto controladas. Aciona imediatamente quando o valor da entrada é alterado pelo usuário (por exemplo, aciona a cada tecla pressionada). Comporta-se como o eventoinput
do navegador.onChangeCapture
: Uma versão deonChange
que aciona na fase de captura.onInput
: Uma funçãoEvent
handler. Aciona imediatamente quando o valor é alterado pelo usuário. Por razões históricas, no React, é idiomático usaronChange
, que funciona de maneira semelhante.onInputCapture
: Uma versão deonInput
que aciona na fase de captura.onInvalid
: Uma funçãoEvent
handler. Aciona se uma entrada falhar na validação ao enviar o formulário. Ao contrário do eventoinvalid
embutido, o eventoonInvalid
do React propaga.onInvalidCapture
: Uma versão deonInvalid
que aciona na fase de captura.onSelect
: Uma funçãoEvent
handler. Aciona após a seleção dentro da<textarea>
mudar. O React estende o eventoonSelect
para também acionar para seleção vazia e em edições (o que pode afetar a seleção).onSelectCapture
: Uma versão deonSelect
que aciona na fase de captura.placeholder
: Uma string. Exibida 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 enviar o formulário.rows
: Um número. Especifica a altura padrão em médias alturas de caracteres. O padrão é2
.wrap
: Pode ser'hard'
,'soft'
ou'off'
. Especifica como o texto deve ser quebrado ao enviar um formulário.
Ressalvas
- Passar filhos como
<textarea>algo</textarea>
não é permitido. UsedefaultValue
para o conteúdo inicial. - Se uma área de texto recebe 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 ao longo de sua vida útil.
- Toda área de texto controlada precisa de um manipulador de eventos
onChange
que atualize sincronamente seu valor de apoio.
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 desabilitar o redimensionamento, você pode especificar resize: none
no CSS.
export default function NewPost() { return ( <label> Escreva seu post: <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 a essa área de texto. Quando o usuário clica no rótulo, o navegador focará a área de texto. Isso também é essencial para acessibilidade: um leitor de tela anunciará a legenda do rótulo quando o usuário focar a á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 seu post: </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 seu post: <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>
ao redor da sua área de texto com um <button type="submit">
dentro. Isso chamará seu manipulador de evento <form onSubmit>
. Por padrão, o navegador enviará os dados do formulário para a URL atual e atualizará a página. Você pode sobrescrever esse comportamento chamando e.preventDefault()
. Leia os dados do formulário com new FormData(e.target)
.
export default function EditPost() { function handleSubmit(e) { // Impedir que o navegador recarregue a página e.preventDefault(); // Ler os dados do formulário const form = e.target; const formData = new FormData(form); // Você pode passar formData como um corpo de fetch diretamente: fetch('/some-api', { method: form.method, body: formData }); // Ou você pode trabalhar com isso como um objeto simples: const formJson = Object.fromEntries(formData.entries()); console.log(formJson); } return ( <form method="post" onSubmit={handleSubmit}> <label> Título do post: <input name="postTitle" defaultValue="Andando de bicicleta" /> </label> <label> Edite seu post: <textarea name="postContent" defaultValue="Eu realmente gostei de andar de bicicleta ontem!" rows={4} cols={40} /> </label> <hr /> <button type="reset">Resetar edições</button> <button type="submit">Salvar post</button> </form> ); }
Controlando uma área de texto com uma variável de estado
Uma área de texto como <textarea />
é não controlada. Mesmo que você vaia uma valor inicial como <textarea defaultValue="Texto inicial" />
, seu JSX especifica apenas o valor inicial, não o valor atual.
Para renderizar uma área de texto controlada, passe a prop value
para ela. O React 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 a 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ê quiser re-renderizar alguma parte da interface do usuário em resposta a cada tecla pressionada.
{ "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 eu digito nela
Se você renderizar uma área de texto com value
mas sem onChange
, verá um erro no console:
// 🔴 Bug: área de texto controlada sem um manipulador onChange
<textarea value={something} />
value
a 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ó queria 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 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 onChange
<textarea value={something} readOnly={true} />
Meu cursor na área de texto salta para o início a cada tecla pressionada
Se você controla uma área de texto, deve atualizar sua variável de estado com o valor da área de texto do DOM durante onChange
.
Você não pode atualizá-la 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á-la 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 adicionada novamente ao DOM a cada tecla pressionada. Isso pode acontecer se você estiver acidentalmente resetando 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 causa o remonte do componente “interno” 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
ao componente, ele deve 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 deve sempre receber uma string value
, não null
ou undefined
.
Se o seu value
estiver vindo de uma API ou variável de estado, pode ser inicializado como null
ou undefined
. Nesse caso, defina-o como uma string vazia (''
) inicialmente, ou passe value={someValue ?? ''}
para garantir que value
seja uma string.