App
component into a healthy state, which is located in the App.js
file of the standard project created by create-react-app. Here is the code: import React, {Component} from "react" class App extends Component { constructor() { super() this.state = {} } render() { return ( <main> <form> <input placeholder="First Name" /><br /> <input placeholder="Last Name" /><br /> <input placeholder="Age" /><br /> {/* */} <br /> {/* */} <br /> {/* */} <br /> <button>Submit</button> </form> <hr /> <h2><font color="#3AC1EF">Entered information:</font></h2> <p>Your name: {/* */}</p> <p>Your age: {/* */}</p> <p>Your gender: {/* */}</p> <p>Your destination: {/* */}</p> <p> Your dietary restrictions: {/* */} </p> </main> ) } } export default App
this.state = { firstName: "", lastName: "", age: 0, gender: "", destination: "", dietaryRestrictions: [] }
age
property, in which it is supposed to store the age entered by the user. Perhaps, otherwise you will need to do with the data storage system flags, which is now represented by the property dietaryRestrictions
, initialized by an empty array.name
attributes so that they match the state property names in which the data entered into these fields will be stored. They must have a value
attribute, the value of which is determined based on the data stored in the state. When entering data into each of these fields, you must pass the entered data to the component, which leads to the need for them to have an onChange
event onChange
. All these arguments lead to the fact that the description of the fields now looks like this: <input name="firstName" value={this.state.firstName} onChange={this.handleChange} placeholder="First Name" /> <br /> <input name="lastName" value={this.state.lastName} onChange={this.handleChange} placeholder="Last Name" /> <br /> <input name="age" value={this.state.age} onChange={this.handleChange} placeholder="Age" />
onChange
events of these fields is specified as non-existent while this.handleChange
. Create this method: handleChange(event) { const {name, value} = event.target this.setState({ [name]: value }) }
name
and value
properties from the event.target
object, and then use them to set the corresponding state property. At the moment, we are satisfied with such a code for a universal event handler, but later, when we get to working with flags, we will make changes to it.this
binding, which is executed in the component's constructor: this.handleChange = this.handleChange.bind(this)
firstName
, secondName
and age
will work with the corresponding <p>
elements, bringing them to the following form: <p>Your name: {this.state.firstName} {this.state.lastName}</p> <p>Your age: {this.state.age}</p>
age
, that is - 0. We also need a hint in the empty field. Let's try to replace the value of age
in the state to null
. After that, it turns out that the form looks as it should, but the console displays the following warning regarding the age
field: Warning: `value` prop on `input` should not be null. Consider using an empty string to clear the component or `undefined` for uncontrolled components
age
with an empty string, bringing the state initialization code to the following form: this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", dietaryRestrictions: [] }
age
field. When filling in the fields, the entered data will be displayed at the bottom of the page.<label>
, which will not only sign the switch, but also make it so that clicking on this <label>
, that is, on its parent element, would lead to its choice.checked
attribute and text fields that have a value
attribute. The switches form a group in which each of the switches is assigned the same name, and the property of the checked
switches is set according to the condition that is configured so that it would not be possible to turn on more than one switch that is included in the same group. onChange
assign this.handleChange
as the onChange
event onChange
switches. <label> <input type="radio" name="gender" value="male" checked={this.state.gender === "male"} onChange={this.handleChange} /> Male </label> <br /> <label> <input type="radio" name="gender" value="female" checked={this.state.gender === "female"} onChange={this.handleChange} /> Female </label>
<p>
element located at the bottom of the page as follows: <p>Your gender: {this.state.gender}</p>
checked
property to checked
true
. After clicking on one of them, the corresponding value (stored in the value
attribute of the switch) is in the state, the switch is selected, the corresponding text is displayed in the lower part of the form. <select> <option></option> <option></option> <option></option> <option></option> </select>
<select>
tag and the <option>
tags in it have a value
attribute. However, these attributes have different meanings. That value
, which is assigned to the <option>
element, indicates what the corresponding state property should be when this element is selected. These are the lines that should be in the drop-down list. In our case, these are certain destinations, for example, countries. Let us write their names with a small letter so that their appearance would correspond to the values ββof the value
properties of other elements in the code. After that, the code of the combo box will look like this: <select value=> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
value
attribute of the <select>
, then there will be indicated not some rigidly specified value, but a link to the corresponding state property: <select value={this.state.destination}> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
onChange
event onChange
, this.handleChange
. <select value={this.state.destination} name="destination" onChange={this.handleChange} > <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
<p>
element, which will display what is selected in the destination
field: <p>Your destination: {this.state.destination}</p>
Your destination:
after the colon.germany
, you need to open a list box, first select something else, and then - the point Germany
.-- Please Choose a destination --
. In our case, it might look like this: <select value={this.state.destination} name="destination" onChange={this.handleChange} > <option value="">-- Please Choose a destination --</option> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
dietaryRestrictions
that the state property dietaryRestrictions
, which is planned to be used for working with flags, was initialized with an empty array. Now, when it came to working with controls, there is a feeling that it would be better to present this field as an object. It will be more convenient to work with entities that represent individual flags as properties of this object with clear names, and not as array elements. The properties of the object, which will now be represented by the state property of dietaryRestrictions
, will contain Boolean values ββindicating whether the corresponding flag is cleared ( false
) or set ( true
). Now the state initialization code will look like this: this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", dietaryRestrictions: { isVegan: false, isKosher: false, isLactoseFree: false } }
<label>
tags and setting their attributes. Here is what their code will look like: <label> <input type="checkbox" name="isVegan" onChange={this.handleChange} checked={this.state.dietaryRestrictions.isVegan} /> Vegan? </label> <br /> <label> <input type="checkbox" name="isKosher" onChange={this.handleChange} checked={this.state.dietaryRestrictions.isKosher} /> Kosher? </label> <br /> <label> <input type="checkbox" name="isLactoseFree" onChange={this.handleChange} checked={this.state.dietaryRestrictions.isLactoseFree} /> Lactose Free? </label>
dietaryRestrictions
object are used as the name of the dietaryRestrictions
, and the constructions of the form this.state.dietaryRestrictions.isSomething
as the values ββof their checked
attributes.this.handleChange
handler that we have is specified as the this.handleChange
event handler for the this.handleChange
, we must make some changes to it in order for the program to work properly.type
and checked
properties from the event.target
object, in addition to those already extracted. The first is needed to check the type of the item (the check boxes are of the type represented by the checkbox
line), the second is to find out if the checkbox is checked or cleared. If it turns out that the handler was called after the user interacts with the flag, we use a special procedure for setting the state. Events of other controls will be processed as before.handleChange
code to the following form. Here we proceed from the assumption that the properties of the dietaryRestrictions
object can be changed one by one: handleChange(event) { const {name, value, type, checked} = event.target type === "checkbox" ? this.setState({ dietaryRestrictions: { [name]: checked } }) : this.setState({ [name]: value }) }
First Name
field, everything will also work as before, but when you try to install one of the check boxes, the following warning will be displayed :Warning: A component is a checkbox to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between the use of the component for the lifetime of the component. More info: fb.me/react-controlled-components
dietaryRestrictions
, you can use the functional form setState
, independently creating a new version of the state. If we had to manage a large number of flags, then we probably would have done so. But here we will do otherwise. Namely, we will make the properties of the object dietaryRestrictions
properties of the state, getting rid of this object: this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", isVegan: false, isKosher: false, isLactoseFree: false }
dietaryRestrictions
: <label> <input type="checkbox" name="isVegan" onChange={this.handleChange} checked={this.state.isVegan} /> Vegan? </label> <br /> <label> <input type="checkbox" name="isKosher" onChange={this.handleChange} checked={this.state.isKosher} /> Kosher? </label> <br /> <label> <input type="checkbox" name="isLactoseFree" onChange={this.handleChange} checked={this.state.isLactoseFree} /> Lactose Free? </label>
<p>Your dietary restrictions:</p> <p>Vegan: {this.state.isVegan ? "Yes" : "No"}</p> <p>Kosher: {this.state.isKosher ? "Yes" : "No"}</p> <p>Lactose Free: {this.state.isLactoseFree ? "Yes" : "No"}</p>
App
component code: import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", isVegan: false, isKosher: false, isLactoseFree: false } this.handleChange = this.handleChange.bind(this) } handleChange(event) { const {name, value, type, checked} = event.target type === "checkbox" ? this.setState({ [name]: checked }) : this.setState({ [name]: value }) } render() { return ( <main> <form> <input name="firstName" value={this.state.firstName} onChange={this.handleChange} placeholder="First Name" /> <br /> <input name="lastName" value={this.state.lastName} onChange={this.handleChange} placeholder="Last Name" /> <br /> <input name="age" value={this.state.age} onChange={this.handleChange} placeholder="Age" /> <br /> <label> <input type="radio" name="gender" value="male" checked={this.state.gender === "male"} onChange={this.handleChange} /> Male </label> <br /> <label> <input type="radio" name="gender" value="female" checked={this.state.gender === "female"} onChange={this.handleChange} /> Female </label> <br /> <select value={this.state.destination} name="destination" onChange={this.handleChange} > <option value="">-- Please Choose a destination --</option> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select> <br /> <label> <input type="checkbox" name="isVegan" onChange={this.handleChange} checked={this.state.isVegan} /> Vegan? </label> <br /> <label> <input type="checkbox" name="isKosher" onChange={this.handleChange} checked={this.state.isKosher} /> Kosher? </label> <br /> <label> <input type="checkbox" name="isLactoseFree" onChange={this.handleChange} checked={this.state.isLactoseFree} /> Lactose Free? </label> <br /> <button>Submit</button> </form> <hr /> <h2><font color="#3AC1EF">Entered information:</font></h2> <p>Your name: {this.state.firstName} {this.state.lastName}</p> <p>Your age: {this.state.age}</p> <p>Your gender: {this.state.gender}</p> <p>Your destination: {this.state.destination}</p> <p>Your dietary restrictions:</p> <p>Vegan: {this.state.isVegan ? "Yes" : "No"}</p> <p>Kosher: {this.state.isKosher ? "Yes" : "No"}</p> <p>Lactose Free: {this.state.isLactoseFree ? "Yes" : "No"}</p> </main> ) } } export default App
Source: https://habr.com/ru/post/446208/
All Articles