我对React Bootstrap相当新,我在创建的表单中遇到了一个令人讨厌的问题。
在状态更新后选中时,他们不会保持检查状态。如果我再次检查它们,他们会的。
我创建了一个切换函数,该函数在状态中附加所选复选框的输入,并将选中的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
答案 0 :(得分:1)
从答案中的e.preventDefault()
函数中删除handleToggle
,无需强制页面刷新。
单击复选框时,React会将先前的值与下一个值进行比较,以确定是否发生了更改。如果有,则更改事件排队。
似乎React在调用handleToggle
之前向DOM查询已检查的值,因此复选框值为True。然后preventDefault()
执行,因此DOM中的复选框值现在为False,但React已将值设置为True。
因此,当preventDefault()
使用复选框(以及可能的单选按钮)时,DOM和React之间会出现不一致。
答案 1 :(得分:0)
对于任何寻找解决方案的人 -
这非常适合选择和取消选中复选框并设置状态,添加和删除选中的值。
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);
}