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
render()
method. In addition, a certain amount of code is responsible for initializing the state of the component. In the component there is also what is called “business logic” (that is, something that implements the logic of the application functioning). This is the code of the handleChange()
method.
render()
method now) and for implementing the logic of the application, that is, by defining how it should look interface (the corresponding code is now represented by the component constructor, in which the state is initialized, and by the event handler of the handleChange()
controls). When using a similar approach to the design of applications, we actually work with two types of components, and it should be noted that you can encounter different names of such components.
App
. This application is designed for the sake of maximally simplifying its structure, but in real projects the App
component hardly makes sense to transfer the task of rendering a form and include code for organizing the work of the internal mechanisms of this form.
App.js
file, the Form.js
file, which will contain the code for the new component. We will transfer all the code from the App
component to this file, and the App
component that is now represented by the component that is based on the class will be transformed into a functional component whose main task will be to output the Form
component. Do not forget to import the Form
component into the App
component. As a result, the App
component code will look like this:
import React, {Component} from "react" import Form from "./Form" function App() { return ( <Form /> ) } export default App
App
component to be something like a “table of contents” for the application, which shows the order in which the sections of the application are displayed, represented by other components that are delegated to rendering large parts of the application.
App
component to the Form
component. Therefore now we will be engaged in the decision of this problem. To do this, create, in the same folder where the Form.js
and App.js
files are located, another file - FormComponent.js
. This file will represent the presentation component responsible for rendering the form. In fact, it can be called differently, it is possible to structure the files of components in a different way, it all depends on the needs and scale of a specific project. The file Form.js
will contain the logic of the functioning of the form, that is, the code of the component container. Therefore, we rename it to FormContainer.js
and change the import command in the code of the App
component, bringing it to this form:
import Form from "./FormContainer"
Form
component in the FormContainer
, but we will not do this. Now let's move the code responsible for rendering the form from the FormContainer.js
file to the FormComponent.js
file.
FormComponent
component will be functional. Here is what its code will look like at this stage of work:
function FormComponent(props) { 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> ) }
this.state.firstName
) and the event handler ( this.handleChange
), which were previously in the same component based on the class in which this rendering code was located. Now everything that was previously taken from the same class in which the rendering code was located will be taken from the properties passed to the component. There are some other problems. Now we will correct this code, but first we will return to the code of the Form
component, which is now in the FormContainer.js
file.
render()
method is now empty. We need the FormComponent
component to be displayed in this method and we need to organize the transfer of the necessary properties to it. We import the FormComponent
into the Form
file and FormComponent
in the render()
method, passing it the event handler, and, as an object, the state. Now the code of the Form
component will look like this:
import React, {Component} from "react" import FormComponent from "./FormComponent" class Form 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( <FormComponent handleChange={this.handleChange} data={this.state} /> ) } } export default Form
FormComponent
code of the FormComponent
component, bringing it to the following form:
import React from "react" function FormComponent(props) { return ( <main> <form> <input name="firstName" value={props.data.firstName} onChange={props.handleChange} placeholder="First Name" /> <br /> <input name="lastName" value={props.data.lastName} onChange={props.handleChange} placeholder="Last Name" /> <br /> <input name="age" value={props.data.age} onChange={props.handleChange} placeholder="Age" /> <br /> <label> <input type="radio" name="gender" value="male" checked={props.data.gender === "male"} onChange={props.handleChange} /> Male </label> <br /> <label> <input type="radio" name="gender" value="female" checked={props.data.gender === "female"} onChange={props.handleChange} /> Female </label> <br /> <select value={props.data.destination} name="destination" onChange={props.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={props.handleChange} checked={props.data.isVegan} /> Vegan? </label> <br /> <label> <input type="checkbox" name="isKosher" onChange={props.handleChange} checked={props.data.isKosher} /> Kosher? </label> <br /> <label> <input type="checkbox" name="isLactoseFree" onChange={props.handleChange} checked={props.data.isLactoseFree} /> Lactose Free? </label> <br /> <button>Submit</button> </form> <hr /> <h2><font color="#3AC1EF">Entered information:</font></h2> <p>Your name: {props.data.firstName} {props.data.lastName}</p> <p>Your age: {props.data.age}</p> <p>Your gender: {props.data.gender}</p> <p>Your destination: {props.data.destination}</p> <p>Your dietary restrictions:</p> <p>Vegan: {props.data.isVegan ? "Yes" : "No"}</p> <p>Kosher: {props.data.isKosher ? "Yes" : "No"}</p> <p>Lactose Free: {props.data.isLactoseFree ? "Yes" : "No"}</p> </main> ) } export default FormComponent
FormComponent
component is still quite large. However, now this code solves only one task, it is responsible only for the visualization of the form. Therefore, working with him is now much easier.
Form
component from the FormContainer.js
file FormContainer.js
now occupied solely by the application logic, and the FormComponent
component from the FormComponent.js
file contains only the code that forms the application interface. The App
component is now only responsible for assembling a page from large blocks.
Redux
and the recently released API Context
, the Container / Component pattern discussed here is no longer as relevant as before. For example, using Redux tools you can maintain a global application state that components can use.
Source: https://habr.com/ru/post/446206/