Контролируемые и неконтролируемые компоненты

внешний интерфейс React.js

Контролируемые и неконтролируемые компоненты: контролируется ли состояние.

1. Реализовать двустороннюю привязку данных с контролируемыми компонентами

Давайте реализуем двустороннюю привязку данных в реакции
Пусть поле ввода введет значение, и дисплей ниже изменится соответствующим образом.

import React,{Component} from 'react';
import ReactDOM from 'react-dom';

class Input extends Component{
    constructor(){
        super();
        this.state={val:''}
    }
    render(){
        return (<div>
            <input type="text" value={this.state.val}/>
            {this.state.val}
        </div>)
    }
}
ReactDOM.render(<Input/>, document.querySelector('#root'));

Но результаты не одинаковы, и мы думали: входное поле не может вводить значения. Это связано с тем, что входное значение принимается в состоянии Val. Но значение Val всегда пусто.Единственный способ изменить состояние — setState.

  • Компоненты, управляемые состоянием, должны иметь метод onChange, иначе их нельзя будет использовать.
  • Управляемым компонентам могут быть присвоены значения по умолчанию (использование контролируемых компонентов официально рекомендуется)
import React,{Component} from 'react';
import ReactDOM from 'react-dom';

class Input extends Component{
    constructor(){
        super();
        this.state={val:'100'}
    }
    handleChange=(e)=>{//e是事件源
        let val=e.target.value;
        this.setState({val});
}
    render(){
        return (<div>
            <input type="text" value={this.state.val} onChange={this.handleChange}/>
            {this.state.val}
        </div>)
    }
}
ReactDOM.render(<Input/>, document.querySelector('#root'));

Простая реализация функции, значение поля ввода унифицировано с отображаемым значением. Это управляемый компонент, управляемый государством.

2. Государственный контроль общедоступных методов контролируемых компонентов

Два поля ввода реализуют функцию суммирования.Если используются два события onchange, код будет избыточным. Мы их сейчас складываем.

import React,{Component} from 'react';
import ReactDOM from 'react-dom';

class Sum extends Component{
    constructor(){
        super();
        this.state={a:1,b:1}
    }
    //key表示的当前状态改的是哪一个
    //e表示的是事件源
    handleChange=(key,e)=>{//处理多个输入框的值映射到状态的方法
        let val=e.target.value;
        this.setState({[key]:val});
}
    render(){
        return (<div>
            <input type="text" value={this.state.a} onChange={(e)=>{
                this.handleChange('a',e)
            }}/>
            <input type="text" value={this.state.b} onChange={(e)=>{
                this.handleChange('b',e)
            }}/>
            {this.state.a+this.state.b}
        </div>)
    }
}
ReactDOM.render(<Sum/>, document.querySelector('#root'));

Таким образом, функцию двух событий onchange можно реализовать через один метод, но вышеописанное — это склейка двух строк, которые нужно преобразовать в числа и добавить, поэтому здесь я этого делать не буду.

3. Неуправляемые компоненты (неподконтрольные государству)

import React,{Component} from 'react';
import ReactDOM from 'react-dom';

//输入框value值不受状态控制,不能初始化默认值
class Sum extends Component{
    constructor(){
        super();
        this.state={result:''}
    }
    //通过ref设置的属性,可以通过this.refs获取到对应的dom元素
    handleChange=()=>{
        let result=this.refs.a.value+this.refs.b.value;
        this.setState({result});
    }
    render(){
        return (<div onChange={this.handleChange}>//运用冒泡的机制不在两个input中添加onchange事件
            <input type="text" ref="a"/>
            <input type="text" ref="b"/>
            {this.state.result}
        </div>)
    }
}
ReactDOM.render(<Sum/>, document.querySelector('#root'));

В приведенной выше реализации два поля ввода не контролируются состоянием. Значение получается при работе с домом, а затем добавляется.Это неуправляемый компонент, отличие которого от управляемого в том, что он не может выдавать значения по умолчанию.

Другой способ реализации ref (рекомендуется)

import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import ErrorBoundary from './components/ErrorBoundary';
import Counter from "./components/Counter";
import Todos from "./components/Todos";
//输入框value值不受状态控制,不能初始化默认值
class Sum extends Component{
    constructor(){
        super();
        this.state={result:''}
    }
    //通过ref设置的属性,可以通过this.refs获取到对应的dom元素
    handleChange=()=>{
        let result=this.refs.a.value+this.b.value;
        this.setState({result});
    }
    render(){
        return (<div onChange={this.handleChange}>//运用冒泡的机制不在两个input中添加onchange事件
            <input type="text" ref="a"/>
            //x代表真实的dom  ,把元素挂载到了当前实例上
            <input type="text" ref={x=>this.b=x}/>
            {this.state.result}
        </div>)
    }
}
ReactDOM.render(<Sum/>, document.querySelector('#root'));

Вторая ссылка на поле ввода дает функцию стрелки,x представляет реальный дом, назначьте настоящий дом текущему экземпляру.