【REACT-受控组件和非受控组件】

概述

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)的构造函数来去实例化子类本身,可以向父级传参
      //必须加this

      this.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'))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值