受控组件: react 接收控制权, 非react的手段不能对元素进行更改. 每一个操作都在react的监控内
非受控组件: 元素的状态不受 react 控制

受控组件

这里给出示例:


image.png
import React from 'react'
export default class extends React.Component {
    state = {
        list: [],
        taskA: '',
        taskB: ''
    }
    handleChange = (e) => {
        this.setState({
            [e.target.name]: e.target.value
        })
    }
    handleAdd = (e) => {
        let type = e.target.name
        let task = this.state[type].trim()
        if(this.state[type].trim() === ''){
            alert('task cannot be null!')
            this.setState({
                title: ''
            })
            return;
        }
        if(type === "taskA"){
            task = `任务A: ${task}`
        } else if(type === 'taskB'){
            task = `任务B: ${task}`
        }
        this.setState({
            list: [...this.state.list, task],
            [type]: ''
        })
    }
    handleDel = (index) => {
        let list = this.state.list
        list.splice(index, 1)
        this.setState({
            list: list
        })

    }
    render() {
        return (
            <div>
                <div>
                    添加任务A: <input name={'taskA'} type="text" onChange={this.handleChange} value={this.state.taskA}/>
                    <button name={'taskA'} onClick={this.handleAdd}>Add</button>
                    <br/>
                    添加任务B: <input name={'taskB'} type="text" onChange={this.handleChange} value={this.state.taskB}/>
                    <button name={'taskB'} onClick={this.handleAdd}>Add</button>
                </div>
                <ul>
                    {
                        this.state.list.map((item, index) => {
                            return (
                                <li key={index}>
                                    <span>{item}</span>
                                    <button onClick={()=>{this.handleDel(index)}}>delete</button>
                                </li>
                            )
                        })
                    }
                </ul>
            </div>
        )
    }
}

比较巧妙地运用了表单的name属性, 完成对组件的实时监控. 不同类型的任务贴上不同类型的标签.

非受控组件

import React from 'react'
export default class extends React.Component {
    state = {
        list: [],
        count: 0
    }
    taskA = React.createRef()
    taskB = React.createRef()
    handleAdd = (e) => {
        let type = e.target.name
        let task = this[type].current.value
        if (type === 'taskA'){
            task = "任务A: " + task
        } else if (type === 'taskB') {
            task = "任务B: " + task
        }
        this.setState({
            list: [...this.state.list, task]
        })
        this[type].current.value = ''
    }
    handleDel = (index) => {
        let list = this.state.list
        list.splice(index, 1)
        this.setState({
            list: list
        })
    }
    render() {
        return (
            <div>
                <div>
                    添加任务A: <input type="text" ref={this.taskA}/>
                    <button name={'taskA'} onClick={this.handleAdd}>Add</button>
                    <br/>
                    添加任务B: <input type="text" ref={this.taskB}/>
                    <button name={'taskB'} onClick={this.handleAdd}>Add</button>
                </div>
                <ul>
                    {
                        this.state.list.map((item, index) => {
                            return (
                                <li key={index}>
                                    <span>{item}</span>
                                    <button onClick={()=>{this.handleDel(index)}}>delete</button>
                                </li>
                            )
                        })
                    }
                </ul>
            </div>
        )
    }
}

ref 的使用方法:
之前是使用 <input ref="name" /> 这样的形式去绑定, react 觉得这样不是很合理, 就废除了, 现在主要有两种方式:

test = React.createRef()
<input type="text" ref={this.taskA}/>
// 此处的 test 是一个对象, 里面只有一个属性 current, 这个属性里是一个dom对象
// 取/赋值方式
this.test.current.value

<input type="text" ref={dom => this.test = dom}/>
// 这个 dom 就是原生的 dom
// 取/赋值方式
this.test.value