【问题标题】:React Bootstrap CheckBox not toggling 'checked' Prop on SelectionReact Bootstrap CheckBox 未在选择时切换“已检查”道具
【发布时间】:2018-01-27 10:20:31
【问题描述】:

我是 React Bootstrap 的新手,我在创建的表单中遇到了一个令人讨厌的问题。

在我的状态更新后被选中时,它们不会保持选中状态。如果我再次检查,他们会的。

我创建了一个切换函数,该函数将来自选定复选框的输入附加到 state 中,并将选中的 prop 设置为 true。 checked={true}

我用两种方法写了,都不起作用。

handleToggle(e) {
    e.preventDefault()
    const selectedBox = "cb" + e.target.value
    this.setState({ goals: this.state.goals + e.target.value, [selectedBox]: e.target.checked })
  }

handleToggle(e) {
    e.preventDefault()
    const selectedBox = "cb" + e.target.value
    this.setState({ goals: this.state.goals + e.target.value, [selectedBox]: true })
  }

令人沮丧的是,状态中的正确值正在更新。我扔了一个调试器,可以看到当前状态包含所选复选框的真实值,并且用户输入附加到当前位于目标键下的任何内容。

任何方向表示赞赏。这需要一段时间来调试。谢谢。

完整的组件 -

import React from 'react';
import { connect } from 'react-redux';
import { Button, form, FormGroup, Checkbox, Radio, option, ControlLabel, FormControl, ProgressBar, Pagination, Form } from 'react-bootstrap';
import DatePicker from "react-bootstrap-date-picker";
import { handleChange } from '../helpers';

class Portfolio extends React.Component {
  constructor(props) {
    super(props)
    var value = new Date().toISOString();
    this.state = {
        date: value,
        experience: 1,
        progress: 0,
        active: false,
        goals: "",
        cb1: false,
        cb2: false,
        cb3: false,
        cb4: false,
        cb5: false
    }
    this.handleSelect = this.handleSelect.bind(this)
    this.handleToggle = this.handleToggle.bind(this)
  }

  handleSelect(eventKey) {
    if (this.state.active === false) {
      this.setState({ experience: eventKey, progress: this.state.progress += 20, active: true })
    } else {
      this.setState({ experience: eventKey })
    }
  }

  handleToggle(e) {
    e.preventDefault()
    const selectedBox = "cb" + e.target.value
    this.setState({ goals: this.state.goals + e.target.value, [selectedBox]: e.target.checked })
  }

  render() {
    const stats = this.props.user.stats
    if (!stats || stats.length === 0) {
      return(
        <div className="portfolio-form-main">
          <div className="portfolio-form-container-title-div">
            <h1 className="portfolio-title">Profile Information</h1>
          </div>
          <div className="portfolio-form-container">
            <form className="portfolio-form">
              <ProgressBar active now={this.state.progress} />
              <FormGroup>
                <ControlLabel>Choose Your Goals.</ControlLabel>
                <Checkbox checked={this.state.cb1} onChange={this.handleToggle} value="1" >
                  Lose Some Weight
                </Checkbox>
                {' '}
                <Checkbox checked={this.state.cb2} onChange={this.handleToggle} value="2">
                  Build Strength and Muscle
                </Checkbox>
                {' '}
                <Checkbox checked={this.state.cb3} onChange={this.handleToggle} value="3">
                  General Health and Wellness
                </Checkbox>
                {' '}
                <Checkbox checked={this.state.cb4} onChange={this.handleToggle} value="4">
                  Compete in an Event
                </Checkbox>
                {' '}
                <Checkbox checked={this.state.cb5} onChange={this.handleToggle} value="5">
                  Rehab an Injury
                </Checkbox>
              </FormGroup>
              <FormGroup>
                <ControlLabel>Rate Your Exercise Experience Level.</ControlLabel>
                <Pagination
                  bsSize="medium"
                  items={10}
                  activePage={this.state.experience}
                  onSelect={this.handleSelect}
                  />
              </FormGroup>
              <FormGroup>
                <ControlLabel>When is Your Birthday?</ControlLabel>
                  {' '}
                <DatePicker value={this.state.value}/>
              </FormGroup>
              <ControlLabel>How Tall Are You?</ControlLabel>
              {' '}
              <Form inline>
                <FormGroup>
                  <FormControl type="number"/>
                  {' '}
                    <FormControl componentClass="select" placeholder="select">
                      <option value="select">Unit</option>
                      <option value="other">in</option>
                      <option value="other">cm</option>
                    </FormControl>
                </FormGroup>
              </Form>
              <ControlLabel>How Much Do You Weigh?</ControlLabel>
              {' '}
              <Form inline>
                <FormGroup>
                  <FormControl type="number"/>
                  {' '}
                    <FormControl componentClass="select" placeholder="select">
                      <option value="select">Unit</option>
                      <option value="other">Lbs</option>
                      <option value="other">Kgs</option>
                    </FormControl>
                </FormGroup>
              </Form>
              <FormGroup >
                <ControlLabel>Tell Us About Yourself.</ControlLabel>
                  {' '}
                <FormControl componentClass="textarea" placeholder="textarea" />
              </FormGroup>
              <Button bsStyle="primary">
                Submit
              </Button>
            </form>
          </div>
        </div>
      )
    }

    return(
      <div>
        <ul>
          <li>{stats.birthdate}</li>
          <li>{stats.weight} {stats.weight_unit}</li>
          <li>{stats.height} {stats.height_unit}</li>
          <li>{stats.experience}</li>
          <li>{stats.about_me}</li>
        </ul>
      </div>
    )
  }


}

export default Portfolio

【问题讨论】:

  • 好吧,我通过在句柄切换功能上进行页面刷新来让它工作。 this.props.requestUser(this.props.match.params.userId); 但这似乎是错误的......所以任何输入仍然赞赏正确处理这个问题。谢谢。

标签: html reactjs react-bootstrap


【解决方案1】:

从您的答案中的 handleToggle 函数中删除 e.preventDefault() 应该消除强制页面刷新的需要。

当一个复选框被点击时,React 会比较前一个值和下一个值来决定是否发生了变化。如果有,则将更改事件排队。

似乎 React 在调用 handleToggle 之前查询 DOM 以获取选中的值,因此复选框值为 True。然后preventDefault() 执行,因此 DOM 中的复选框值现在为 False,但 React 已将值设置为 True。

因此,当使用 preventDefault() 和复选框(可能还有单选按钮)时,DOM 和 React 之间会出现不一致。

【讨论】:

  • 欢迎来到 SO!不要抱歉,只需在 e.preventDefault() 周围添加更多细节,以及 OP 如何检测到这是未来的问题,这将是一篇很棒的帖子!在那之后,3 年后,当我们看到你的代表达到 100 或 1000 时,你的评论会看起来有点奇怪;)
【解决方案2】:

对于任何寻求解决方案的人--

这非常适用于选择和取消选择复选框和设置状态,添加和删除选中的值。

handleToggle(e) {
    e.preventDefault()
    const selectedBox = "cb" + e.target.value
    if (this.state.goals.includes(e.target.value)) {
      const goal = this.state.goals.replace(e.target.value, '')
      this.setState({ goals: goal, [selectedBox]: e.target.checked })
    } else {
      this.setState({ goals: this.state.goals + e.target.value, [selectedBox]: e.target.checked })
    }
    this.props.requestUser(this.props.match.params.userId);
  }

【讨论】:

    猜你喜欢
    • 2023-02-23
    • 2018-10-30
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    • 1970-01-01
    相关资源
    最近更新 更多