- Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
Looking at the previous articles on JSX interaction, the user’s actions on the page are all carried over by forms, so the next form processing is the focus.
Form processing (JSX Interaction)
Forms processing in React is actually the interaction logic between the user and the application, and the interaction between the application and the user is carried on by forms. Therefore, what we actually learn is the interaction between JSX and the user’s form data.
In React, forms are divided into controlled and uncontrolled forms.
React managed forms: The values of form elements are managed by React. The values of form elements are stored in state, so the values of form elements need to be retrieved from state.
Uncontrolled forms: They are not controlled by React management. The data of form elements is managed by the DOM element itself. The values of form elements are also stored in the DOM element.
React’s basic logic is that data determines the UI, so React must control data, and uncontrolled forms do not conform to this basic logic, and are rarely encountered in actual development. The focus is on controlled forms.
Next, look at a handful of them through specific code.
Controlled Components (forms)
We use a normal form that displays the data in state:
import React, { Component } from 'react'
export class Tables extends Component {
state = {
name:"xiling"
}
render() {
return (
<div>
<input type="text" value={this.state.name} />
</div>
)
}
}
export default Tables
Copy the code
Page is rendered in the form and content is completely no problem, but when we try to modify the form data in the page, you will find that cannot be modified, but also an error, this and the previous study of the state of the modified conditions are consistent, cannot be directly modified, need through the setState () method for data change, the code is as follows:
changes = (ev)=>{
this.setState({
name:ev.target.value
})
}
render() {
return (
<div>
<input type="text" value={this.state.name} onChange={this.changes} />
</div>
)
}
}
Copy the code
The form is modified by user input, that is, whatever value the user enters into the form is changed to the corresponding value of state.
This operation, need to get it to the form of user input, at the same time we also need to know when the user is trigger modification action, so, we need to form a binding a value changed this action triggers onChange events, after the event, the event handler receives the event object (ev) in order to get the user modify the content, The data is then modified by setState().
There is nothing wrong with this logic, but if we have two forms, we need two event handlers, if we have three forms, four forms, ten forms…
import React, { Component } from 'react'
export class Tables extends Component {
state = {
name:"xiling",
age:18
}
changes = (ev)=>{
this.setState({
name:ev.target.value
})
}
ages = (ev)=>{
this.setState({
age:ev.target.value
})
}
render() {
return (
<div>
<input type="text" value={this.state.name} onChange={this.changes} />
<input type="text" value={this.state.age} onChange={this.ages} />
</div>
)
}
}
export default Tables
Copy the code
The most intuitive way to change this is to remove the individual event handlers and write the event handler directly to the event binding, as in:
render() {
return (
<div>
<input type="text" value={this.state.name}
onChange={(ev)=>{
this.setState({name:ev.target.value})
}}
/>
<input type="text" value={this.state.age}
onChange={(ev)=>{
this.setState({age:ev.target.value})
}}
/>
</div>
)
}
Copy the code
However, even so, there is still a problem that you need to write the modification logic separately for each form. Once there are many forms, it is also a very difficult problem. Can the modification of forms be managed uniformly?
Of course you can! We can do this using form attributes.
We add a name attribute to each form that matches the value of the property in state, so we can get the value of the form’s property in the event handler, because it’s consistent with state, so, We can use the form property directly as the value of the state property to modify, as follows:
import React, { Component } from 'react'
export class Tables extends Component {
state = {
name:"xiling",
age:18
}
tables = (ev)=>{
const prop = ev.target.name
this.setState({
[prop]:ev.target.value
})
}
render() {
return (
<div>
<input type="text" name="name" value={this.state.name} onChange={this.tables} />
<input type="text" name="age" value={this.state.age} onChange={(ev)=>this.tables(ev)} />
</div>
)
}
}
export default Tables
Copy the code
Finally, we will solve the error reporting problem. The reason for the error is already clear in the console. Controlled forms require corresponding event handling to control data changes, and if not, an error will occur.
However, if I only want to display the data in the form, and I don’t want to control the change, I still get this error, which is very unfriendly, what should I do? There are two solutions, both very simple, so let’s look at them.
Render () {return (<div> {/* Render () {return (<div> {/* */} <input type="text" value={this.state.name} readOnly onChange={(ev) => {this.setState({name: Ev.target. value})}} /> {/* } <input type="text" defaultValue={this.state.age} /> </div>) }Copy the code
Common examples of controlled forms
Controlled drop-down list
import React, { Component } from 'react'
export class Tables extends Component {
state = {
subject: "HTML"
}
render() {
return (
<div>
<p>{this.state.subject}</p>
<select name="" id="" value={this.state.subject}
onChange={
(ev) => this.setState(
{ subject: ev.target.value }
)
}>
<option value="JS">JS</option>
<option value="HTML">HTML</option>
<option value="CSS">CSS</option>
</select>
</div>
)
}
}
export default Tables
Copy the code
Controlled single option box
import React, { Component } from 'react' export class Tables extends Component { state = { sex: } render() {return (<div> <p>{this.state.sex}</p> <input type=" name "="sex" id="" value=" male" onChange={(ev)) => this.setState({ sex: Ev.target. value})} /> male <input type="radio" name="sex" id="" value=" female "onChange={(ev) => this.setState({sex: Ev.target. value})} /> female <input type="radio" name="sex" id="" value=" "onChange={(ev) => this.setState({sex: Ev.target. value})} /> Monster </div>)}} export default TablesCopy the code
Controlled check box
import React, {Component} from 'react' export class Tables extends Component {// {id:1,title:'HTML',isChecked:false}, {id:2,title:'JS',isChecked:true}, {id:3,title:'CSS',isChecked:false}, ] checks = (index,ev)=>{ // console.log(ev.target.checked) // console.log(index) this.Datas[index].isChecked = Ev.target.checked} render() {return (<div> <h2> check box </h2> {this.datas.map ((data,index)=>{return (<label) Key ={data.id}> {/* Use the onChange event binding, pass the subscript and event object, */} <input type="checkbox" defaultChecked={data.ischecked} onChange={(ev)=>{this.checks(index,ev)}} /> {data.title} </label>)})} <button onClick={()=>console.log(this.datas)} > Display multi-box content data </button> </div>)}} export default TablesCopy the code
Uncontrolled form
In most cases, we recommend using controlled forms to process form data. In a controlled component, form data is managed by the React component. Another alternative is to use uncontrolled forms, where the form data is handed over to DOM nodes for processing.
Whereas controlled forms require writing data handlers for each status update, with uncontrolled forms you can use refs to retrieve form data from DOM nodes.
The original writing
React will add the ref attribute to the entire page and place it in an array. Use this.refs to fetch the ref attribute.
import React, { Component } from 'react' export class Tables extends Component { gets = ()=>{ console.log(this.refs.users.value) } Render () {return (< div > < input type = "text" ref = 'users' / > < button onClick = {() = > this. Gets ()} > get < / button > < / div >)}} export default TablesCopy the code
However, this usage will cause a warning message in the browser for the simple reason that strict mode is enabled by default in the new React version.
Warning: A string ref, “users”, has been found within a strict mode tree.
We need to remove the strict mode code from the index.js entry as follows:
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,document.getElementById(‘root’)
);
This is what it looks like, and the error message disappears:
ReactDOM.render(
<App />,
document.getElementById('root')
);
Copy the code
Canonical writing
However, this method is not good, don’t ask why, it is not good, we recommend using the following method:
import React, { Component } from 'react' export class Tables extends Component { constructor (){ super() this.myref = React.createRef() } gets = ()=>{ console.log(this.myref.current.value) } render() { return ( <div> <input type="text" Ref ={this.myref} /> <button onClick={()=>this.gets()}> </button> </div>)}} export default TablesCopy the code
The react-generated ref (createRef()) method is used to normalize the react-generated ref.
However, it is important to note that either way, it is enough to know, uncontrolled forms, if possible, do not use, why ah? How dare you bring home something you can’t control?
However, because uncontrolled forms store real data in DOM nodes, it is sometimes easier to integrate React and non-React code together when using uncontrolled forms. If you don’t care about code aesthetics and want to write code quickly, using uncontrolled components can often reduce your code load. Otherwise, you should use controlled components.
conclusion
In application page, and basic user interactions are presented in the form, framework design concept, according to the React to form rendering work, must be in the charge of framework, and the form data interaction needs must receive framework control and dependence, and controlled form is we should use the way of the form, but uncontrolled form code more obviously, Uncontrolled forms exist to retrieve the Dom in special cases and are not officially recommended, even though uncontrolled forms seem more useful.
conclusion
React basic Grammar section, this is the end of the road, I have tears in my eyes, I cut through the thorns, I am lost, I really not easy……
Although not easy, but, I so good-looking, how could it be so over, do not write a case is too indecent!
In the next chapter… It will be finished by 2023! ง ง, _, ()