Вопрос по поводу setState() в react

275
08 июля 2017, 11:28

Здравствуйте. Я хотел спросить по поводу поведения метода setState в react. Как я понимаю, вызвав его, мы устанавливаем значение переменной компонента (например переменную color), затем автоматически вызывается метод render().
Допустим результаты render() зависят от переменной color. Но setState({color:"red"}), не меняет эту переменную мгновенно, и метод render вполне может получить старое значение color. В таком случае получается запаздывание отображения на один ход. Как быть в таком случае?

Ниже я привел рабочий пример, для валидации формы.

  1. Поле "логин" и "пароль" валидны если содержат 3 и более символа.
  2. Поле "повтор пароля" валидно если оно равно полю "пароль" и если поле "пароль" валидно.
  3. кнопка отправить активна если все текстовые поля валидны.

class Input extends React.Component { 
 
    constructor(props) { 
        super(props); 
        this.state = {isValid: false}; 
        this.inputValueChanged = this.inputValueChanged.bind(this); 
    } 
 
    inputValueChanged(e) { 
        var txt = e.target.value; 
        this.state.isValid = txt.length >= 3; 
        this.state.text = txt; 
        this.props.checkToUnblockSubmit(); 
    } 
 
    render() { 
        return React.createElement('input', { 
            className: "form-control", 
            onChange: this.inputValueChanged, 
            placeholder: this.props.placeholder, 
            type: this.props.type, 
            style: {borderColor: this.state.isValid ? "green" : "red"} 
        }, null); 
    } 
} 
 
 
class Form extends React.Component { 
 
    constructor(props) { 
        super(props); 
        this.state = {repeatIsValid: false, allInputsValid: false}; 
        this.checkToUnblockSubmit = this.checkToUnblockSubmit.bind(this); 
        this.saveRepeatValue = this.saveRepeatValue.bind(this); 
        this.send = this.send.bind(this); 
    } 
 
    checkToUnblockSubmit() { 
        this.state.repeatIsValid = this.refs.password.state.isValid && (this.refs.password.state.text === this.state.repeatText); 
        this.state.allInputsValid = this.refs.login.state.isValid && this.refs.password.state.isValid && this.state.repeatIsValid; 
        this.setState(); 
    } 
 
    saveRepeatValue(e) { 
        this.state.repeatText = e.target.value; 
        this.checkToUnblockSubmit(); 
    } 
 
    send() { 
       console.log("здесь мы отправляем"); 
    } 
 
    render() { 
        return ( 
            React.createElement('div', null, 
 
                React.createElement('div', {className: "form-group"}, 
                    React.createElement(Input, { 
                        type: "text", 
                        ref: "login", 
                        placeholder: "логин", 
                        checkToUnblockSubmit: this.checkToUnblockSubmit 
                    }, null)), 
 
                React.createElement('div', {className: "form-group"}, 
                    React.createElement(Input, { 
                        type: "password", 
                        ref: "password", 
                        placeholder: "пароль", 
                        checkToUnblockSubmit: this.checkToUnblockSubmit 
                    }, null)), 
 
                React.createElement('div', {className: "form-group"}, 
                    React.createElement('input', { 
                        type: "password", 
                        ref: "repeat", 
                        className: "form-control", 
                        placeholder: "повторить пароль", 
                        style: {borderColor: this.state.repeatIsValid ? "green" : "red"}, 
                        onChange: this.saveRepeatValue 
                    }, null)), 
 
                React.createElement('div', {className: "form-group"}, 
                    React.createElement('button', {                         
                        className: this.state.allInputsValid ? "btn btn-success" : "btn btn-danger", 
                        disabled: !this.state.allInputsValid, 
                        onClick: this.send 
                    }, 'отправить'))                     
            ) 
        ) 
    } 
} 
 
ReactDOM.render( 
    React.createElement(Form, null, null), 
    document.getElementById('container') 
);
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="container"></div>

Такой вариант работал не корректно:

this.setState({
  repeatIsValid : this.refs.password.state.isValid && (this.refs.password.state.text === this.state.repeatText),
  allInputsValid : this.refs.login.state.isValid && this.refs.password.state.isValid && this.state.repeatIsValid
})

И поэтому для корректной работы мне пришлось сделать так :

 this.state.repeatIsValid = this.refs.password.state.isValid && (this.refs.password.state.text === this.state.repeatText);
 this.state.allInputsValid = this.refs.login.state.isValid && this.refs.password.state.isValid && this.state.repeatIsValid;
 this.setState();

правильно ли было так делать?

READ ALSO
Как переключать слайды в owl-carousel стрелками клавиатуры?

Как переключать слайды в owl-carousel стрелками клавиатуры?

В документации к библиотеке не нашел реализации прокрутки слайдов стрелками клавиатурыКак это можно реализовать? Нужно чтобы при нажатии...

431
Первый элемент с классом

Первый элемент с классом

Подскажите, где ошибся

241
Генерация текстов

Генерация текстов

Добрый день всем!

260
Перебор цикла для вывода списка (постов например) Вордпресс

Перебор цикла для вывода списка (постов например) Вордпресс

Всем приветРаботаю сейчас с Вордпрессом и столкнулся с проблемой

197