【REACT
REACT-受控组件和非受控组件
- 概述
- 受控组件
- 非受控组件
- 受控组件应用ToDoList
概述
React中的组件根据是否受React控制可分为受控的和非受控的。
React 中的受控组件和非受控组件都是针对于表单数据而言的。React 推荐使用受控组件来处理表单数据。
受控组件
在一个受控组件中,表单数据是由 React 组件来管理的。
import React, { Component} from 'react'
import ReactDOM from "react-dom";
export default class App extends Component {state = {value:'初始值'}render() {return (<div><input type="text" value={this.state.value} onChange={(evt)=>{this.setState({value:evt.target.value})}}/><button onClick={()=>{console.log(this.state.value)}}>登录</button><button onClick={()=>{this.setState({value:""})}}>重置</button><Child value={this.state.value}></Child></div>)}
}class Child extends Component {render() {return (<div>{this.props.value}</div>)}
}ReactDOM.render(// <React.StrictMode><App />// </React.StrictMode>,document.getElementById('root'))
非受控组件
在非受控组件中,表单数据交由 DOM 节点处理,可以使用 ref 来从 DOM 中获取表单数据
import React, { Component} from 'react'
import ReactDOM from "react-dom";
export default class App extends Component {myref = createRef(); // state = {// value:'初始值'// }render() {return (<div>{/* 想React 能赋予组件一个初始值,但是不去控制后续的更新 可以指定defaultValue*/}{/* 同样, <input type="checkbox"> 和 <input type="radio"> 支持 defaultChecked , <select>和 <textarea> 支持 defaultValue 。*/}<input type="text" ref={this.myref} defaultValue="初始值" onChange={(evt)=>{this.setState({value:evt.target.value})}}/><button onClick={()=>{console.log(this.myref.current.value)}}>登录</button><button onClick={()=>{this.myref.current.value = "";}}>重置</button>{/* 非受控组件中,dom元素数据(this.myref.current.value)不能进行外部的分享,可以使用状态中的数据进行传递 */}{/* <Child value={this.myref.current.value}></Child> */}{/* <Child value={this.state.value}></Child> */}</div>)}
}class Child extends Component {render() {return (<div>{this.props.value}</div>)}
}ReactDOM.render(// <React.StrictMode><App />// </React.StrictMode>,document.getElementById('root'))
受控组件应用ToDoList
import React, { Component} from 'react'
import ReactDOM from "react-dom";
export default class ToDoList extends Component {constructor(){//构造器//子类必须调用super()super();//super 调用了父类(Component)的构造函数来去实例化子类本身,可以向父级传参//必须加thisthis.state = {todoList:[{id:1,text:'eat',isChecked:false},{id:2,text:'sleep',isChecked:true},{id:3,text:'run',isChecked:true},],value:'',}}//外部变量可以直接写// state = {// todoList:[11,22,33]// }render() {return (<div><input value={this.state.value} onChange={(evt)=>{this.setState({value:evt.target.value})}}></input><button onClick={()=> this.add()}>添加</button><ul>{this.state.todoList.map((item,index) => {return (<li key={item.id} >{/*数据需要进行删除和添加的话,key最好是使用唯一辨识值id*/ }{/*dangerouslySetInnerHTML的作用相当于VUE中的v-html*/}<input type="checkbox" checked={item.isChecked} onChange={()=>this.handleChecked(index)}/><span dangerouslySetInnerHTML={{__html:item.text}} style={{textDecoration:item.isChecked?'line-through':''}}></span><button onClick={()=>this.del(index)}>del</button></li>)})}</ul>{this.state.todoList.length === 0 && <div>暂无待办事项2</div>}{/*第一个条件为真才会执行后面的条件,否则不执行 */}{/* {this.state.todoList.length === 0?<div>暂无待办事项1</div>:null}<div>{this.state.todoList.length === 0 && '暂无待办事项3'}</div> */}</div>)}add(){let newList = [...this.state.todoList];//尽量不要直接更改原对象newList.push({id:this.state.todoList.length+1,text:this.state.value,isChecked:false});this.setState({todoList:newList,value:''});}del(index){//浅克隆// let newList = this.state.todoList.concat();let newList = this.state.todoList.slice();newList.splice(index,1);this.setState({todoList:newList});}handleChecked(index){let newList = this.state.todoList.slice();newList[index].isChecked = !newList[index].isChecked;this.setState({todoList:newList});}
}ReactDOM.render(// <React.StrictMode><ToDoList />// </React.StrictMode>,document.getElementById('root'))