Реактивная функция флажка только с одним выбором - PullRequest
2 голосов
/ 19 сентября 2019

Я хочу выяснить, неправильн ли мой код или ошибка.Я думаю, что нет проблем, но это не работает ...

Код, который я использовал: https://codepen.io/cadenzah/pen/wvwYLgj?editors=0010

class ItemView extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      options: [{
        id: 1,
        name: "Item 1"
      },
      {
        id: 2,
        name: "Item 2"
      }],
      optionSelected: 2
    }
  }

  toggleCheckbox(e) {
    console.log(e.target.id)
    if (this.state.optionSelected === e.target.id) {
      this.setState({
        optionSelected: undefined
      })
    } else {
      this.setState({ optionSelected: e.target.id })
    }
  }

  render() {
    return (
      <div className="container">
        <div className="row">
          <ItemList
            options={this.state.options}
            optionSelected={this.state.optionSelected}
            toggleCheckbox={(e) => this.toggleCheckbox(e)} />
        </div>
      </div>
    )
  }
}

const ItemList = ({ options, optionSelected, toggleCheckbox }) => {
  return (
    <div className="col s12">
      {
        options.map((option, index) => (
          <Item
            key={index}
            option={option}
            checked={(optionSelected === (index + 1) ? true : false)}
            toggleCheckbox={toggleCheckbox} />
        ))
      }
    </div>
  )
}

const Item = ({ option, checked, toggleCheckbox }) => {
  return (
    <div className="card">
      <div className="card-content">
        <p><label htmlFor={option.id}>
          <input 
            className="filled-in"
            type="checkbox"
            id={option.id}
            onChange={toggleCheckbox}
            checked={(checked ? "checked" : "")} />
          <span>{option.id}. {option.name}</span>
          </label></p>
      </div>
    </div>
  )
}

Объяснение кода:

Код реагирования, с использованием materialize-css.

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

Основная логика: в компоненте <ItemList /> имеется условный реквизит , который определяет, должен ли быть каждый элементпроверено или нет.Он сравнивает идентификатор и передает true или false своим дочерним элементам.То, что checked props используется в компоненте <Item /> для установки атрибута checked <input>.

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

В чем проблема?

Ответы [ 3 ]

1 голос
/ 19 сентября 2019

Вы можете проверить, является ли выбранная опция отмеченной, как это:

checked={optionSelected === option.id}

И затем вы просто получаете это в свой ввод, как это:

<input checked={checked} />

Также, сделайтеОбязательно измените свои идентификаторы состояния на строки (идентификатор элемента DOM имеет тип string):

  options: [{
    id: '1',
    name: "Item 1"
  },
  {
    id: '2',
    name: "Item 2"
  }],
  optionSelected: '2'

https://codepen.io/AndrewRed/pen/gOYBVPZ?editors=0010

1 голос
/ 19 сентября 2019
class ItemView extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      options: [{
        id: 1,
        name: "Item 1"
      },
      {
        id: 2,
        name: "Item 2"
      }],
      optionSelected: 2
    }
  }

  toggleCheckbox(e) {

    this.setState({
      optionSelected : e.target.id
    })
   }

  render() {
    return (
      <div className="container">
        <div className="row">
          <ItemList
            options={this.state.options}
            optionSelected={this.state.optionSelected}
            toggleCheckbox={(e) => this.toggleCheckbox(e)} />
        </div>
      </div>
    )
  }
}

const ItemList = ({ options, optionSelected, toggleCheckbox }) => {

  return (
    <div className="col s12">
      {
        options.map((option, index) => (
          <Item
            key={index}
            option={option}
            checked={(optionSelected === (index + 1) ? true : false)}
            toggleCheckbox={toggleCheckbox} 
            optionSelected = {optionSelected}
            />
        ))
      }
    </div>
  )
}

const Item = ({ option, checked, toggleCheckbox,optionSelected }) => {
  return (
    <div className="card">
      <div className="card-content">
        <p><label htmlFor={option.id}>
          <input 
            className="filled-in"
            type="checkbox"
            id={option.id}
            onChange={toggleCheckbox}
            checked={option.id == optionSelected ? "checked" : ""} />
          <span>{option.id}. {option.name}</span>
          </label></p>
      </div>
    </div>
  )
}

function tick() {
  ReactDOM.render(
    <ItemView />,
    document.getElementById('root')
  );
}

tick()

КОПИРОВАНИЕ И ПУСК

1 голос
/ 19 сентября 2019

e.target.id - это string, а index - это число.Когда вы делаете === сравнение, тип также проверяется, и они не совпадают.Это приводит к тому, что флажок всегда равен false после исходного состояния (которое вы задали себе как int)

...