javascript - React splice 无法与 Checkbox 中的数组一起正常工作
问题描述
我有一个允许多个复选框的表单。当用户单击复选框时,应该将值添加到对象数组中,并且当用户取消单击时,将从数组中删除该值,但这不起作用,除非该值是最后添加到数组中的。
编码:
import React, { useState, useEffect } from 'react';
import { Dialog, DialogTitle, DialogContent, makeStyles, ListItemSecondaryAction } from '@material-ui/core';
import { Button, ButtonToolbar } from 'react-bootstrap';
import Grid from '@material-ui/core/Grid';
import * as FaIcons from 'react-icons/fa';
import './FilterPopup.css'
import { filterData } from './filterData';
import { genresData } from './genresData'
export default function Filter(props) {
const { title, children, openPopup, setOpenPopup, genres, setGenres } = props;
const [filtergenres, setFilterGenres] = useState([]);
var index;
function verify(elem) {
for (var i = 0; i < filtergenres.length; i++) {
var obj = filtergenres[i];
if (obj.id == elem) {
console.log(obj);
index = i;
console.log(index);
return true;
} else {
return false;
}
}
}
function changeValue(elem) {
console.log(elem);
let newlist = filtergenres;
if (verify(elem)) {
console.log(index);
newlist.splice(index, 1);
setFilterGenres(newlist);
console.log(newlist);
console.log(filtergenres);
} else {
newlist.unshift({
id: elem,
value: elem
});
setFilterGenres(newlist);
console.log(newlist);
console.log(filtergenres);
}
}
return (
<Dialog open={openPopup} className='filterDialog' maxWidth="md">
<DialogTitle>
<div className='popupTitle'> Filter </div>
<Button className='popupCloseBtn' onClick={() => { setOpenPopup(false) }}>
<FaIcons.FaTimes />
</Button>
</DialogTitle>
<DialogContent dividers>
<form className='pop-up-forms'>
<label className='popuppart'>
Sort By:
<select className='filter-sort'>
{filterData.map((item, index) => {
return (
<option key={index} value={item.value}>{item.title}</option>
)
})}
</select>
<Button className='popupSearchSubmitBtn' onClick={() => { }}>
submit
</Button>
</label>
<label className='popuppart'>
Include Adult:
<input
className='filterchkbox'
name="isAdult"
type="checkbox" />
</label>
<label className='filterGenres'>
Genres:
<Grid container spacing={1} direction="row" justify="center" alignItems="center">
{genresData.map((item, index) => {
return (
<Grid item key={index}>
<label className='genresLabel'>
{item.name}
<input
className='filterchkbox'
name="isAdult"
type="checkbox"
value={item.id}
onClick={() => { changeValue(item.id) }} />
</label>
</Grid>
)
})}
</Grid>
</label>
</form>
</DialogContent>
</Dialog >
)
}
这页纸:
在照片中,我按以下顺序单击了选项:
动作(值:28)、冒险(值:12)、动画(值:16)、喜剧(值:35)然后我取消了动画。但是代码再次添加了 16。如果我再次单击动画以重新检查它,那么它将删除它刚刚添加的 16。
解决方案
splice
并且unshift
不要以不可变的方式编辑数组(参考保持不变)。React 的变更检测机制仅由新引用触发。如果您仍想使用splice
并且unshift
可以先创建数组的副本 ( const clone = [...newlist];
),请在其上调用函数,然后将其传递给setFilterGenres
. 这种方式引用将改变,React 将能够看到这种变化。
推荐阅读
- javascript - 在 vuejs 的 v-for 中使用 img src
- direct3d - 如何在对象之前渲染子窗口?
- json - 在 Flutter/Dart 中从 JSON 数组中提取数据
- android - 有时我的应用程序在以 API 28 为目标后因 android.view.InflateException 而崩溃
- r - 如何告诉 readr::read_csv 正确猜测双列
- apache - htaccess RewriteRule:在第一个参数之后省略所有的问题
- python - 如何为组合框选择正确的列
- parquet - 嵌套 JSON 到 Parquet
- xamarin.forms - xamarin 形成不在 db3 文件中的 sqlite-net-pcl 表
- spring - 使用 Gradle 的 MongoDB Spring Batch 作业