jeudi 19 septembre 2019

React checkbox feature with only single selection

I want to figure out whether my code is wrong or a bug. I think there is no problem, but it does not work...

The code I used is: 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>
  )
}

Code explaination:

React code, with materialize-css used.

It is a simple checkbox feature with multiple items, restricted to select only one item. So, if I check one of them, every item except for what I just selected will be unchecked automatically. If I uncheck what I just checked, every item will stay unchecked.

The core logic is: in <ItemList /> component, there is a conditional props that determines whether each item has to be checked or not. It compares the id, and hand in true or false into its children. That checked props is used in <Item /> component to set the checked attribute of <input>.

Strange thing is, as I set default choice in the initial state, when I just run the application, the check feature works as I expected. But if I click one of them, it does not work.

What is the problem of it?




Aucun commentaire:

Enregistrer un commentaire