Вопрос по onchange, checkbox, reactjs – Реактивный чекбокс не отправляется на изменение

81

TLDR: используйте defaultChecked вместо флажка, здесь работает jsbinhttp://jsbin.com/mecimayawe/1/edit?js,output

Попытка установить простой флажок, который зачеркнет текст метки при его проверке. По какой-то причине handleChange не срабатывает при использовании компонента. Может кто-нибудь объяснить, что я делаю не так?

var CrossoutCheckbox = React.createClass({
  getInitialState: function () {
    return {
        complete: (!!this.props.complete) || false
      };
  },
  handleChange: function(){
    console.log('handleChange', this.refs.complete.checked); // Never gets logged
    this.setState({
      complete: this.refs.complete.checked
    });
  },
  render: function(){
    var labelStyle={
      'text-decoration': this.state.complete?'line-through':''
    };
    return (
      <span>
        <label style={labelStyle}>
          <input
            type="checkbox"
            checked={this.state.complete}
            ref="complete"
            onChange={this.handleChange}
          />
          {this.props.text}
        </label>
      </span>
    );
  }
});

Использование:

React.renderComponent(CrossoutCheckbox({text: "Text Text", complete: false}), mountNode);

Решение:

Использование флажка не позволяет (по-видимому) изменить базовое значение и, следовательно, не вызывает обработчик onChange. Переключение на defaultChecked, кажется, исправляет это:

var CrossoutCheckbox = React.createClass({
  getInitialState: function () {
    return {
        complete: (!!this.props.complete) || false
      };
  },
  handleChange: function(){
    this.setState({
      complete: !this.state.complete
    });
  },
  render: function(){
    var labelStyle={
      'text-decoration': this.state.complete?'line-through':''
    };
    return (
      <span>
        <label style={labelStyle}>
          <input
            type="checkbox"
            defaultChecked={this.state.complete}
            ref="complete"
            onChange={this.handleChange}
          />
          {this.props.text}
        </label>
      </span>
    );
  }
});
Вот так все и началось, но, похоже, никогда не обновлялось. Так что я начал разбрасывать это тут и там, чтобы отлаживать то, что не было уволено. В идеале вернемся к простейшей форме, когда закончим :) jdarling
Во-первых, почему бы не добавить onChange, который просто делаетthis.setState({checked: !this.state.checked}) Проще, чем хранить значение. Затем троичный оператор в проверенном атрибуте:checked={this.state.checked ? 'checked': null} zackify
Он может просто использовать состояние вместо получения узла dom:jsfiddle.net/d10xyqu1/1 Это работает нормально, вы, должно быть, что-то опечатали. zackify
Предполагая, что ваш mountNode является фактическим dom-узлом, вам придется использоватьthis.refs.complete.getDOMNode().checked, увидеть скрипкуjsfiddle.net/d10xyqu1 trekforever
Игнорировать комментарий TLDR - defaultChecked не всегда ответ Chris

Ваш Ответ

6   ответов
1

Если у тебя естьhandleChange функция, которая выглядит так:

handleChange = (e) => {
  this.setState({
    [e.target.name]: e.target.value,
  });
}

Вы можете создать кастомonChange функция так, что она действует как ввод текста:

<input
  type="checkbox"
  name="check"
  checked={this.state.check}
  onChange={(e) => {
    handleChange({
      target: {
        name: e.target.name,
        value: e.target.checked,
      }
    });
  }}
/>
неhandleChange наinput должно бытьthis.handleChange? Ardhi
Это зависит от того, где и как вы это определяете, но в большинстве случаев, вероятно, да. spencer.sm
1

В пользовательском интерфейсе состояние флажка можно получить как

this.refs.complete.state.switched
129

Чтобы получить проверенное состояние вашего флажка, путь будет:

this.refs.complete.state.checked

Альтернатива состоит в том, чтобы получить его от события, переданного вhandleChange метод:

event.target.checked
установкаchecked означает, что состояние управляется вне компонента. Когда пользователь нажимает, звонить нечегоhandleChange так как ни одно состояние не обновляется. Вместо этого вам нужно будет слушатьonClick и вызвать обновление состояния там. zbyte
Но почему - с той же проблемой, но вы должны использоватьchecked для контролируемых компонентов: / Dominic
Вот и все ... Искал вечно, оглядываясь по сторонам. Обновит вопрос с полным рабочим ответом на случай, если другие столкнутся с этим тоже. jdarling
Попробуйте использовать defaultChecked = {this.state.complete} вместо «проверено» на вводе. zbyte
handleChange никогда не вызывается, не имеет значения, если вы установите флажок или метку, handleChange не будет вызван :(. jdarling
6

который вы НЕ хотели бы использовать обработчик onChange на входной DOM, вы можете использоватьonClick собственность как альтернатива.defaultCheckedусловие может выйти из фиксированного состояния для VINM v16.

 class CrossOutCheckbox extends Component {
      constructor(init){
          super(init);
          this.handleChange = this.handleChange.bind(this);
      }
      handleChange({target}){
          if (target.checked){
             target.removeAttribute('checked');
             target.parentNode.style.textDecoration = "";
          } else {
             target.setAttribute('checked', true);
             target.parentNode.style.textDecoration = "line-through";
          }
      }
      render(){
         return (
            <span>
              <label style={{textDecoration: this.props.complete?"line-through":""}}>
                 <input type="checkbox"
                        onClick={this.handleChange}
                        defaultChecked={this.props.complete}
                  />
              </label>
                {this.props.text}
            </span>
        )
    }
 }

Я надеюсь, что это поможет кому-то в будущем.

9

В таких случаях лучше не использовать ссылки. Использование:

<input
    type="checkbox"
    checked={this.state.active}
    onClick={this.handleClick}
/>

Есть несколько вариантов:

checked противdefaultChecked

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

onClick противonChange

Первый всегда будет срабатывать при кликах. Последний не будет срабатывать при кликах, еслиchecked атрибут присутствует наinput элемент.

1

льзовании defaultChecked. В качестве альтернативы вы можете использовать onClick и onTouchEnd.

<input onClick={this.handleChange} onTouchEnd={this.handleChange} type="checkbox" defaultChecked={!!this.state.complete} />;

Похожие вопросы