,

React中表单

表单主要有受控组件和非受控组件。 受控组件 无论是学习 Vue,还是 React,最重要的是要转换思想,这一步…

表单主要有受控组件和非受控组件。

受控组件

无论是学习 Vue,还是 React,最重要的是要转换思想,这一步非常重要,往往也比较困难。

在以前 jQuery 时代,开发人员需要获取到 DOM 节点,然后进行操作。而在现代前端开发中,采用的是 MVVM 的模式,将视图和视图模型进行绑定,视图模型的改变,会自然的带来视图的改变。开发人员需要专注在视图模型上面。

因此,这里所谓的受控组件,本质上其实就是将表单中的控件和视图模型(状态)进行绑定,之后都是针对状态进行操作。

下面,我们来看一些具体的案例:

  • 一个基本的受控组件
import React from "react";

// 类组件
class App extends React.Component {
 state = {
   value : ""
}

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

 clickHandle = () => {
   // 提交整个表单
   console.log(`你要提交的内容为:${this.state.value}`);
}

 render() {
   return (
     <div>
       <input type="text" value={this.state.value} onChange={this.handleChange}/>
       <button onClick={this.clickHandle}>提交</button>
     </div>
  )
}

}

export default App;
  • 对用户输入的内容进行限制
import React from "react";

// 类组件
class App extends React.Component {
 state = {
   value1 : "",
   value2 : ""
}

 handleChange = (e) => {
  const name = e.target.name;
  switch(name){
   case "one": {
     // 用户输入的是第一个输入框
     // 只能输入大写
     this.setState({
       value1 : e.target.value.toUpperCase()
    })
     break;
  }
   case "two":{
     // 用户输入的是第二个输入框
     // 只能输入数字
     const newValue = e.target.value.split("").map(item=>{
       if(!isNaN(item)){
         return item
      }
    }).join("");
     this.setState({
       value2 : newValue
    })
     break;
  }
  }
}

 clickHandle = () => {
   // 提交整个表单
   console.log(`你要提交的内容为:${this.state.value}`);
}

 render() {
   return (
     <div>
       <input
         type="text"
         name="one"
         value={this.state.value1}
         onChange={this.handleChange}
         placeholder="自动转为大写"
       />
       <input
         type="text"
         name="two"
         value={this.state.value2}
         onChange={this.handleChange}
         placeholder="只能输入数字"
       />
       <button onClick={this.clickHandle}>提交</button>
     </div>
  )
}

}

export default App;
  • 文本域
import React from "react";

// 类组件
class App extends React.Component {
 state = {
  value : ""
}

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

 clickHandle = () => {
   // 提交整个表单
   console.log(`你要提交的内容为:${this.state.value}`);
}

 render() {
   return (
     <div>
       <textarea
         cols="30"
         rows="10"
         value={this.state.value}
         onChange={this.handleChange}
       />
       <button onClick={this.clickHandle}>提交</button>
     </div>
  )
}

}

export default App;
  • 多选框
import React from "react";

// 类组件
class App extends React.Component {
 state = {
   checkBoxs: [
    { content: "html", checked: false },
    { content: "css", checked: false },
    { content: "js", checked: false },
    { content: "vue", checked: false },
    { content: "react", checked: false },
  ],
}

 handleChange = (index) => {
   const arr = [...this.state.checkBoxs];
   arr[index].checked = !arr[index].checked;
   this.setState({
     checkBoxs: arr
  })
}

 clickHandle = () => {
   // 提交整个表单
   console.log(this.state.checkBoxs);
}

 render() {
   return (
     <div>
       <div>
        {
           this.state.checkBoxs.map((item, index) => (
             <div key={index}>
               <input
                 type="checkbox"
                 value={item.content}
                 checked={item.checked}
                 onChange={()=>this.handleChange(index)}
               />
               <span>{item.content}</span>
             </div>
          ))
        }
       </div>
       <button onClick={this.clickHandle}>提交</button>
     </div>
  )
}

}

export default App;
  • 下拉列表
import React from "react";

// 类组件
class App extends React.Component {
 state = {
   value : "html"
}

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

 clickHandle = () => {
   // 提交整个表单
   console.log(this.state.value);
}

 render() {
   return (
     <div>
       <select value={this.state.value} onChange={this.handleChange}>
         <option value="html">HTML</option>
         <option value="css">CSS</option>
         <option value="js">JS</option>
         <option value="vue">Vue</option>
         <option value="react">React</option>
       </select>
       <button onClick={this.clickHandle}>提交</button>
     </div>
  )
}

}

export default App;

非受控组件

大多数情况下,在 React 中推荐使用受控组件来对表单进行操作,这样能够对表单控件的数据进行一个统一管理。

但是在某些特殊情况下,需要使用以前传统的 DOM 方案进行处理,此时替代的方案就是非受控组件。

  • 非受控组件基本示例
import React from "react";

// 类组件
class App extends React.Component {

 constructor(){
   super();
   // 创建了一个 ref,回头我们就可以获取到和该 ref 绑定了的 DOM 节点
   this.inputCon = React.createRef();
}

 clickHandle = () => {
   // 通过 this.inputCon.current 可以获取到 input DOM 节点
   console.log(this.inputCon.current.value);
}


 render() {
   return (
     <div>
       <input type="text" ref={this.inputCon}/>
       <button onClick={this.clickHandle}>获取用户输入的内容</button>
     </div>
  )
}

}

export default App;
  • 非受控组件的默认值
<div>
{/* 一旦你用了 value,React 会认为你这是一个受控组件 */}
{/* 如果想要给默认值,使用 defaultValue */}
 <input type="text" ref={this.inputCon} defaultValue="123"/>
 <button onClick={this.clickHandle}>获取用户输入的内容</button>
</div>
  • 文件上传
import React from "react";

// 类组件
class App extends React.Component {

 constructor() {
   super();
   // 创建 ref 的时候,命名一般采用 xxxRef 结尾
   this.uploadRef = React.createRef();
}

 clickHandle = () => {
   // 通过 this.uploadRef.current 可以获取到 input DOM 节点
   console.log(this.uploadRef.current.files);
}


 render() {
   return (
     <div>
       <input type="file" ref={this.uploadRef}/>
       <button onClick={this.clickHandle}>获取用户输入的内容</button>
     </div>
  )
}

}

export default App;

Next Post

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor