【问题标题】:React checkbox feature with only single selection反应复选框功能只有一个选择
【发布时间】:2020-01-20 07:11:45
【问题描述】:

我想弄清楚我的代码是错误还是错误。我认为没有问题,但它不起作用......

我使用的代码是: 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>
  )
}

代码说明:

React 代码,使用了materialize-css

这是一个包含多个项目的简单复选框功能,仅限于选择一个项目。因此,如果我选中其中一个,除了我刚刚选择的项目之外的每个项目都将自动取消选中。如果我取消选中我刚刚选中的内容,则每个项目都将保持未选中状态。

核心逻辑是:在&lt;ItemList /&gt;组件中,有一个conditional props来决定每一项是否必须被检查。它比较 id,并将 truefalse 提交给它的孩子。 checked 组件中使用 &lt;Item /&gt; 组件来设置 &lt;input&gt;checked 属性。

奇怪的是,当我在初始状态下设置默认选项时,当我刚刚运行应用程序时,检查功能按预期工作。但是如果我点击其中一个,它就不起作用了。

它有什么问题?

【问题讨论】:

  • 我认为你应该尝试使用 refs,ID 不适合 react

标签: javascript reactjs checkbox materialize


【解决方案1】:

e.target.id 是一个 stringindex 是一个数字。当您进行=== 比较时,还会检查类型,但它们并不相同。这会导致在初始状态(您将自己设置为 int)之后 checked 始终为 false

【讨论】:

  • 这是一个很好的观点。我忘记了 id 属性是 string 值。谢谢。
【解决方案2】:

您可以像这样检查所选选项是否为选中的选项:

checked={optionSelected === option.id}

然后您只需像这样将其放入您的输入中:

<input checked={checked} />

另外,请确保将您的状态 ID 更改为字符串(DOM 元素 ID 是字符串类型):

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

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

【讨论】:

    【解决方案3】:
    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()
    

    复制粘贴并运行

    【讨论】:

      猜你喜欢
      • 2013-10-21
      • 1970-01-01
      • 2017-08-10
      • 2015-02-11
      • 1970-01-01
      • 2018-06-23
      • 2015-06-06
      • 1970-01-01
      相关资源
      最近更新 更多