How to bypass the <textarea> default value not showing up issue in React

Introduction

This post is to show case how did I bypass the <textarea>problem with defaultValue. In React, value is Uncontrolled Components, which means subsequent update is not possible. Therefore, defaultValue is used instead. React document says that <textarea>also supports defaultValue, however, when it did not show the preset value as expected. As a result, something is needed to be set up to bypass this dilemma.

Prelude

While working on my Capstone project, I came to the need of creating an update form to update the existing events. Since it’s an update form, therefore previous values are necessary to be preset to be the default values of the update form fields. In my case, One of the form fields is a <textarea>tag, and since the `value` tag in React is an

<textarea
name=’symptoms’
type=’text’
defaultValue={event.symptoms}
required
id=’AddEventForm__symptoms’>
</textarea>
the symptoms field did not have the preset value

My first attempt

My first attempt was to search on Google, and from one of the stackoverflow post How to add default value for html textarea? I notice that I can put the value between the <textarea> tags as following.

<textarea>
...put your default value here
</textarea>
index.js:1437 Warning: Use the `defaultValue` or `value` props instead of setting children on <textarea>.
in textarea (at EditEventForm.js:127)
in div (at EditEventForm.js:123)
in form (at EditEventForm.js:49)
in EditEventForm (at EditEventPage.js:28)
in div (at EditEventPage.js:26)
in EditEventPage (created by Context.Consumer)
in Route (at App.js:62)
in Switch (at App.js:32)
in main (at App.js:31)
in div (at App.js:26)
in App (at src/index.js:14)
in EventProvider (at src/index.js:12)
in EventListProvider (at src/index.js:11)
in Router (created by BrowserRouter)
in BrowserRouter (at src/index.js:10)

To reason a way out

After thinking for a while, I noticed that in order for the value to be preset, I will have to use the value, but the value tag is immutable, so perhaps I can set up a state property, which is set to have the same value of the preset value of the value tag. So when I key down to make changes, the update will happen from the end of that value onward. To do this I will also need an onChange handler function to update the state property in real time, which in turns will update the <textarea> form field. After messing around for a while, I finally got it to work(see the figure be). The code snippets are as follow.

state setup

This setup the property inside state

export default class EditEventForm extends Component{state = {
error:null,
symptoms:this.context.event.symptoms
}

handler setup

The handler function get the updated value from event.target from the form , then it updates the state property


...
handleChangeSymptoms = e => {
this.setState({ symptoms: e.target.value })
}
...

`<textarea>` form field setup

This calls the onChange handler function whenever it detects changes in the field, then it set the value to the handler and updates the state.

...
<textarea
name='symptoms'
type='text'
value={this.state.symptoms}
onChange={this.handleChangeSymptoms}
required
id='AddEventForm__symptoms'>
</textarea>
...
The symptoms field has the preset value

Full Stack Developer, with a passion in Blockchain and Data Science

Full Stack Developer, with a passion in Blockchain and Data Science