Использование логических операторов для условного включения / выключения элемента кнопки - PullRequest
0 голосов
/ 14 февраля 2019

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

В моей функции обработчика событий onChange:

  • Я обновляю состояния, связанные с моими полями, тем самым обновляя поля ввода
  • Inв той же функции-обработчике я объявляю логическое значение, основанное на цепочке логических операторов каждого состояния, для которого необходимо значение, используя '&&'
  • . Присвойте результат! состоянию с именем buttonDisabled
  • ThisЗатем состояние присваивается свойству «disabled» кнопки
  • По умолчанию состояние отключенного свойства равно true

Код

onInputChange = (e) => {
    e.preventDefault();
    const newValue = e.target.value;

    const targetElement = e.target.id;
    this.setState(() => {

        return {
            entryInput: newValue, 
            [targetElement]: newValue
        }
    })

    this.setState( () => {
        let buttonState =
        (this.state.symbol && 
        this.state.contracts &&
        this.state.open);
        return {
            buttonDisabled: buttonState
        }

    })

}

На моем элементе кнопки:

<Button disabled={this.state.buttonDisabled} onClick={...} ?>

Ожидаемый результат - «Отправить» отключен до тех пор, пока все состояния не содержат значений (т. Е. Все поля имеют значения)

Фактический результат - «Отправить» отключен, но активируется на второмзапись последнего текстового поля, которое я заполняю.

  • Я зарегистрировал полученное логическое значение в консоли, и оно соответствует точным условиям
  • Кнопка включения / выключения, кажется, является обновлением позади
  • ThiУчитывая, что && возвращает логические значения / значения, я явно использовал сравнения с === '' и той же проблемой.Я также попробовал оператор if / else

Возможно, у меня где-то здесь есть логический пробел, но я немного крутил свои колеса, и было бы здорово получить немного помощи.

спасибо

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Вам не нужно хранить значение в состоянии, вы можете фактически выполнить проверку в самой функции render .По по умолчанию функция render вызывается каждый раз, когда вызывается setState :

import React from "react";
import ReactDOM from "react-dom";

class Form extends React.Component {
  constructor() {
    super();
    this.state = {
      name: "",
      age: ""
    };
  }

  nameChange = (e) => {
    this.setState({ name: e.target.value });
  };

  ageChange = (e) => {
    this.setState({ age: e.target.value });
  };

  submit = () => {
    const { name, age } = this.state;
    alert(`name: ${name} is age: ${age}`);
  };

  render() {
    const { name, age } = this.state;
    const enabled = name.length > 0 && age.length > 0;
    return (
      <form onSubmit={this.submit}>
        <input
          type="text"
          placeholder="Enter name"
          value={this.state.name}
          onChange={this.nameChange}
        />
        <input
          type="text"
          placeholder="Enter age"
          value={this.state.age}
          onChange={this.ageChange}
        />
        <button disabled={!enabled}>Submit</button>
      </form>
    );
  }
}

const root = document.getElementById("root");
ReactDOM.render(<Form />, root);

Также имейте в виду:

setState () не изменяет немедленно this.state, но создает ожидающий переход в состояние.Доступ к this.state после вызова этого метода может потенциально вернуть существующее значение.Нет гарантии синхронной работы вызовов setState, и вызовы могут быть сгруппированы для увеличения производительности.

0 голосов
/ 14 февраля 2019

Я думаю, вам нужно изменить второй setState так, чтобы вы принимали состояние в качестве входного параметра:

this.setState((newState) => {
    let buttonState =
    (newState.symbol && 
    newState.contracts &&
    newState.open);
    return {
        buttonDisabled: buttonState
    }
})

В общем, если вы используете состояние внутри setState updater fn, вам нужно использоватьсостояние, которое передается в качестве параметра в updater, а не this.state.

Я полагаю, что это потому, что вызовы setState не гарантируются как немедленные, а в случае нескольких вызовов они могут бытьставятся в очередь и применяются в пакетном режиме.Другими словами, в вашем случае обновления применяются только к this.state после запуска fns, поэтому, если вы полагаетесь на this.state, то второй setState updater fn не увидит эффекта первого setState updater fn,Если второму fn требуется доступ к результату первого, вам нужно использовать предоставленное значение промежуточного состояния.

Это объясняется гораздо лучше в разделе «Передача функции в setState ()» этого урока:https://css -tricks.com / понимание-реагировать-settate / # article-header-id-1

А также в официальных документах здесь: https://reactjs.org/docs/react-component.html#setstate.Эта цитата из документации является ключевой:

Думайте о setState () как о запросе, а не как о немедленной команде для обновления компонента.Для лучшего восприятия производительности React может задержать ее, а затем обновить несколько компонентов за один проход.React не гарантирует, что изменения состояния будут применены немедленно.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...