react受控组件和非受控组件

1. 非受控组件

React 要编写一个非受控组件,可以使用ref 来从DOM节点中获取表单数据,就是非受控组件。例如下面的代码使用非受控组件接受一个表单的值:

import React, { Component } from 'react'
export default class App extends Component {
  myusername=React.createRef()
  render() {
    return (
        <div>
            {/* 非受控写法 */}
            <h1>登录页</h1>
            <input type="text" ref={this.myusername} defaultValue="huanhuan"/>
            <button onClick={()=>{console.log(this.myusername.current.value)}}>登录</button> 
            <button onClick={()=>{console.log(this.myusername.current.value="")}}>Reset</button> 
      </div>
    )
  }
}

2. 受控组件

在HTML中,标签<input>、<textarea>、<select>的值的改变通常是根据用户输入进行更新。在React中,可变状态通常保存在组件的状态属性中,并且只能使用 setState() 更新,而呈现表单的React组件也控制着在后续用户输入时该表单中发生的情况,以这种由React控制的输入表单元素而改变其值的方式,称为:“受控组件”。

import React, { Component } from 'react'
import Child from './components/Child'
export default class App extends Component {
    myusername = React.createRef()
    state = {
        username: 'kerwin'
    }
    render() {
        return (
            <div>
                {/* 受控写法  只需要通过控制 this.state 传值方式即可 */}
                <h1>登录页</h1>
                <input type="text" ref={this.myusername} value={this.state.username}
                   
                    onChange={(event) =>
                        {
                            console.log(event.target.value);
                            this.setState({
                            username:event.target.value
                            })
                        }
                    }/>
                <button onClick={() => { console.log(this.state.username); }}>登录</button>
                <button onClick={() => {
                    // console.log(this.myusername.current.value = "")
                    this.setState({
                        username:""
                        })
                }}>Reset</button>
                 {/* 子组件也可以通过传值方式 */}
                <Child myvalue={this.state.username}></Child>
            </div>
        )
    }
}

3. 受控组件案例 列表查询

import React, { Component } from 'react'
export default class Cinema extends Component {
    constructor() {
        super()
        this.state = {
            cinemalist: [{ cinameId: 1, name: "水晶草", address: "北京市朝阳区西大望路蓝堡国际中心1座2101" },
                { cinameId: 2, name: "李晓艺", address: "北京市通州区西大望路蓝堡国际中心1座2106" },
                { cinameId: 3, name: "李乐乐", address: "北京市朝阳区西大望路蓝堡国际中心1座2106" },
                { cinameId: 4, name: "李佳佳", address: "北京市朝阳区西大望路蓝堡国际中心1座2106" }],
            mytext:""
        }
    }
    //后面讲的声明周期函数 更适合发送ajax
    render() {
        return (
            <div>
                <input type="text" value={this.state.mytext} onChange={(evt) => {
                    this.setState({
                        mytext:evt.target.value
                    })
                }} />
                {
                    this.getCinemalist().map((item) =>
                        <dl key={item.cinameId}>
                            <dt>{item.name}</dt>
                            <dd>{item.address}</dd>
                        </dl>
                    )
                }
            </div>
        )
    }
    getCinemalist() {
        let mytext = this.state.mytext.toUpperCase()
        return this.state.cinemalist.filter(item => item.name.toUpperCase().includes(mytext) || item.address.toUpperCase().includes(mytext))
        
    }
}
// filter
//filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素

4. 受控组件案例 list增加和删除

import React, { Component } from 'react'
export default class app extends Component {
    a = 100;
    myref = React.createRef()

    state = {
      list:[{
          id: "1",
          mytext: "春天来了",
          isChecked:false
      },{
        id: "2",
          mytext: "冬天走了,春天还远吗",
          isChecked:false
    },{
        id: "3",
          mytext: "春天来了,夏天还远吗",
          isChecked:true
            }],
        mytext:""
    };
   
  render() {
      var newList= this.state.list.map((item,index) => <li key={index}>{item.key}</li> )
    return (
        <div>
            <input ref={this.myref} value={this.state.mytext} onChange={(event) => { this.setState({ mytext: event.target.value }) } } /> 
            <button onClick={this.handleClick2}>add2</button>
            <ul>
                {
                    this.state.list.map((item,index)=>
                        <li key={item.id}>
                            <input type="checkbox" checked={item.isChecked} onChange={() => 
                                this.handleChange(index)} />
                            <span style={{textDecoration:item.isChecked?"line-through":""}} dangerouslySetInnerHTML={{__html: item.mytext}}></span>
                            <input onClick={()=>this.handleDelClick(index)} type="button" value="del" />
                        </li>
                    )
                }
            </ul>         
            <div className={this.state.list.length === 0?'':'hidden'}> 待办事项暂无!</div>
      </div>
    )
    }
    handleChange = (index) => {
        console.log(index)
        let newlist = [...this.state.list]
        newlist[index].isChecked = !newlist[index].isChecked
        this.setState({
            list:newlist
        })
    }
    handleClick2 = () => {
        this.state.list.push({ "mytext": this.myref.current.value,id:Math.random()*111111})
      this.setState({list:this.state.list})
    }
    handleDelClick = (id) => {
        console.log("click2", id)
        let newlist = this.state.list.concat() //拷贝一个数组 slice(0)   [...arr]     Array.from(arr)  Object.assign([],arr);
        newlist.splice(id, 1)
        this.setState({list:newlist})
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容