我想允许用户从复选框中选择一周中的几天。选中复选框后,该复选框的值应更新this.state.days。它不是添加到数组中,而是简单地覆盖this.state.days。尝试使用简单的扩展运算符,但我得到一个错误,指示反应不能将null转换为对象 - 这甚至发生在我将天数设置为[1,2]时,因此它在开始时未定义。请参阅下面的更改功能
this.state = {
days:[]
}
handleDaySelect (event) {
if (this.state.days) {
var dayArr = [...this.state.days]
} else {
var dayArr = [];
}
dayArr.push(event.target.value)
this.setState({
days: dayArr
})
}
渲染功能:
render() {
const daysOptions = ["Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday"].map((cur, ind) => {
return (
<div key={ind} className="checks" >
<label>
<input type="checkbox" name={cur} value={cur}
onChange={this.handleDaySelect} />{cur}
</label>
</div>
)
})
return (
<div id="newDeal" className="formContainer" >
<div className="checkBoxContainer" >
{daysOptions}
</div>
</div>
)
}
答案 0 :(得分:3)
handleDaySelect(event){
let day_list = this.state.days;
let check = event.target.checked;
let checked_day = event.target.value;
if(check){
this.setState({
days: [...this.state.days, checked_day]
})
}else{
var index = day_list.indexOf(checked_day);
if (index > -1) {
day_list.splice(index, 1);
this.setState({
days: day_list
})
}
}
}
希望这有帮助。
答案 1 :(得分:1)
setState
是异步的。
因此,当您根据以前的值设置状态时,您应该使用功能setState
。
(有关原因的信息,here's a good read)
根据您的说明,您也可能在错误的地方设置state
,或者您没有bind
您的功能{{} 1}}。
handleDaySelect
但是,为了使其工作,您需要以不同于select的方式处理取消选择。因此,您的onChange应检查是否需要附加新值或删除现有值。这可能有点单调乏味。
只需存储day-gt; boolean的地图,即可让您的生活更轻松。 (here's another question解决了同样的问题)
class DaySelector extends Component {
// state as a static property. You can also use `getInitialState` or set `this.state` in your constructor.
state = {
days: []
}
// use an arrow function or `bind(this)` in the constructor
handleSelect = e => {
// grab the checkbox value since functional setState is async and won't have access to `e` without calling persist
const { value } = e.target
// functional setState because we're building off of the previous state
this.setState(prevState => ({
// copy over any other values from state
...prevState,
days: [
...prevState.days,
value
]
})
}
}
然后,要获取所选日期的列表,您可以这样做:
const DAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
class DaySelector extends Component {
state = {
days: DAYS.reduce(
(state, day) => ({ ...state, [day]: false }),
{}
)
}
handleSelect = e => {
const { name, checked } = e.target
this.setState(prevState => ({
...prevState,
days: {
...prevState.days,
[name]: checked
}
})
}
render() {
return (
// Using Fragments from React 16.2, but divs are fine too
<>
{
Object.keys(this.state.days).map(day => (
<Fragment key={day}>
<input
type="checkbox"
name={day}
checked={this.state.days[day]}
onChange={this.handleSelect}
/>
{day}
</Fragment>
))
}
</>
)
}
}
(有关我使用片段的详情,请参阅this question和the documentation)
答案 2 :(得分:0)
您需要检查以前是否存在该值,如果不是,则必须添加它,否则将其删除。你也应该确保写作
this.state = {
days:[]
}
在
之类的构造函数中constructor() {
super();
this.state = {
days:[]
}
}
或者如果你要写一个类属性
state = {
days:[]
}
另请不要忘记bind
您的handleDaySelect
功能。
段:
handleDaySelect = (event) => {
var dayArr = [...this.state.days];
const value = event.target.value
const index = dayArr.findIndex(day => day === value);
if(index > -1) {
dayArr = [...dayArr.slice(0, index), ...dayArr.slice(index + 1)]
} else {
dayArr.push(value);
}
this.setState({days: dayArr});
}
答案 3 :(得分:0)
而不是在dayArr
中定义handleDaySelect
我在外面宣布它,以便可以将新选择的日期推入其中。然后可以将其设置为应用的新状态每次点击(以前每天选择更多)。虽然您每次点击都会重写状态,但您不会丢失之前选定的日期。
this.state = {
days:[]
}
let dayArr;
handleDaySelect (event) {
/*now we should check if the selected days
already exist so that we don't double entry it*/
if (this.state.days.indexOf(event.target.value) < 1) {
dayArr.push(event.target.value)
}
this.setState({
days: dayArr
})
}
我希望它可以帮到你,如果你在js小提琴上或类似的地方分享你的代码会更好。
谢谢:)