您好,我想知道如何将“不确定”应用到我的代码复选框示例:
我知道文档就在那里,但我无法让它发挥作用,这是我的尝试,我想说我已经很接近了,但显然错过了一些非常重要的东西
这个想法是,当我单击“父级”时,所有这些都被单击,所有这些都更改为选中状态,并且所有这些都将数据发送到变量,当我取消单击时,它们应该删除它,当我删除其中一个时特别是它应该只删除那个特别的(那个已经在工作但我不知道我是否必须为父级添加其他东西)
他们分别做了我想做的事情,但我想添加父/主要的,这样我就可以检查所有这些:
这是我的代码:
[根据我迄今为止收到的帮助编辑代码]
//Functions
//set all students
const [allStudentsID, setAllStudentsID] = useState([]);
const setAllStudents = () => {
setAllStudentsID(Array.isArray(estudiantes) ? allStudentsID.length && estudiantes.length === allStudentsID.length ? [] : estudiantes.map(x=> x.id):[]);
console.log(allStudentsID)
}
console.log 如下所示:
//set individual one by one (works)
const [studentID, setStudentID] = useState([])
const setStudent = (estudiante) => {
if(!studentID.find(id => id === estudiante)){
setStudentID([ ... studentID, estudiante]);
}
else {
setStudentID(studentID.filter(studentId => studentId !== estudiante))
}
console.log(studentID)
}
Mapping/Render:
//Titles (not sure if I'm setting up correctly the checkbox)
<thead>
<tr className="Lista">
<Checkbox
color = "primary"
id = "checkBox"
onChange = {() => setAllStudents()}
checked={allStudentsID.length === estudiantes.length}
indeterminate={allStudentsID.length > 0 && allStudentsID.length < estudiantes.length}
/>
<th>Nombre</th>
<th>Colegio</th>
<th>Grado</th>
<th>Accion</th>
</tr>
</thead>
//Table (this works)
{estudiantes.map((estudiantes, index) => (
<tr key={estudiantes.id || index}>
<td>
<Checkbox
checked={!!studentID.find( id => id === estudiantes.uid)}
color = "primary"
id = "checkBox"
onChange = {() => setStudent(estudiantes.uid, index)}
inputProps={{ 'aria-label': 'controlled' }}
/>
</td>
... some code that will finish the table
根据您的代码和问题,当您使用
estudiantes.uid
处理复选框状态时,它可以工作,但是在 setAllStudents
函数中,您使用的是 x.label
,它在数组中不存在,那就是为什么你的控制台日志显示 undefined
。也许尝试更新函数以从函数返回 id
。
将状态初始化为空数组
const [allStudentsID, setAllStudentsID] = useState([]);
更新
setAllStudents
来检查这两个条件,如果所有复选框都已选中,则将状态数组重置为空数组,否则选择全部。
const setAllStudents = () => {
setAllStudentsID(Array.isArray(estudiantes) ? allStudentsID.length && estudiantes.length === allStudentsID.length ? [] : estudiantes.map(x=> x.id):[]);
console.log(allStudentsID)
}
还请为标题中的复选框提供
checked
和 indeterminate
属性。
<Checkbox
color = "primary"
id = "checkBox"
onChange = {() => setAllStudents()}
checked={allStudentsID.length === estudiantes.length} // if both are equal, that means all were already selected
indeterminate={allStudentsID.length > 0 && allStudentsID.length < estudiantes.length}
/>
我从头开始编写代码:
代码中的注释。
import { Fragment, useState } from "react";
import Box from "@mui/material/Box";
import Checkbox from "@mui/material/Checkbox";
import { Card } from "@mui/material";
const estudiantes = [
{ uid: 1, label: "Student 1" },
{ uid: 2, label: "Student 2" },
{ uid: 3, label: "Student 3" }
];
const App = () => {
const [checkedStudents, setCheckedStudents] = useState([]);
const handleChange1 = (isChecked) => {
if (isChecked)
return setCheckedStudents(
estudiantes.map((estudiante) => estudiante.uid)
);
else setCheckedStudents([]);
};
const handleChange2 = (isChecked, uid) => {
const index = checkedStudents.indexOf(uid);
// The checked value is altered before the state changes for some reason is not a trully controlled component
// So the next conditions are INVERTED.
if (isChecked) return setCheckedStudents((state) => [...state, uid]);
if (!isChecked && index > -1)
return setCheckedStudents((state) => {
state.splice(index, 1);
return JSON.parse(JSON.stringify(state)); // Here's the trick => React does not update the f* state array changes even with the spread operator, the reference is still the same.
});
};
return (
<Fragment>
{/* Parent */}
<Checkbox
checked={checkedStudents.length === estudiantes.length}
indeterminate={
checkedStudents.length !== estudiantes.length &&
checkedStudents.length > 0
}
onChange={(event) => handleChange1(event.target.checked)}
/>
{/* Childrens */}
<Box sx={{ display: "flex", flexDirection: "column", ml: 3 }}>
{checkedStudents &&
estudiantes.map((estudiante) => (
<Checkbox
key={estudiante.uid}
checked={checkedStudents.includes(estudiante.uid)}
onChange={(event) =>
handleChange2(event.target.checked, estudiante.uid)
}
inputProps={{ "aria-label": "controlled" }}
/>
))}
</Box>
<h3>ID's: {JSON.stringify(checkedStudents)}</h3>
</Fragment>
);
};
export default App;
我找到了一个解决方案,但必须更改为常规复选框,然后使这个主题解决了一半,因为到目前为止我们还没有找到解决方案来正确使用 Material UI 复选框,无论如何,我将把它留在这里,这是常规的输入复选框。
//Variable that will provide the data (mine updates from firebase so not gonna add all that code)
const [estudiantes, setEstudiantes] = useState([]);
//Variable that will hold all the data
const [studentsID, setStudentsID] = useState([]);
//Function
const handleChange = (e, data) => {
const { name, checked } = e.target;
if (checked) {
// if cheked and selectall checkbox add all fileds to selectedList
if (name === "allSelect") {
setStudentsID(estudiantes);
} else {
// if cheked and specific checkbox add specific field to selectedList
setStudentsID([...studentsID, data]);
}
} else {
// if uncheked and selectall checkbox add remove all fileds from selectedList
if (name === "allSelect") {
setStudentsID([]);
} else {
// if uncheked and specific checkbox remove specific field from selectedList
let tempuser = studentsID.filter((item) => item.id !== data.id);
setStudentsID(tempuser);
}
}
console.log(studentsID)
};
//Main select checkbox
<input
type="checkbox"
className="form-check-input"
name="allSelect"
checked={studentsID?.length === estudiantes?.length}
onChange={(e) => handleChange(e, estudiantes)}
/>
//Checkboxs inside the .map
<tbody>
{estudiantes.map((estudiantes, index) => (
<tr key={estudiantes.id || index}>
<td>
<input
type="checkbox"
className="form-check-input"
name={estudiantes.uid}
checked={studentsID.some((item) => item?.uid === estudiantes.uid)}
onChange={(e) => handleChange(e, estudiantes)}
/>
</td>
//Some nonrelevant code for this question ...
};
免责声明,这个答案不是我的,我从教程中找到它:React JS 中的所有选择复选框和一个示例:示例我只是根据我的需要调整了它。
如果有人通过 Material UI 复选框找到正确的解决方案,请告诉我。
反应性较小,但很短。
您可以将其指定为字符串(或不指定),以便它成为输入上的标准“可见”属性:
function SomeComponent({ indeterminate }) {
return <input type="checkbox" indeterminate={indeterminate && String(indeterminate)} />;
}
然后它也可以用普通的 css 来设计样式
input[type='checkbox']:indeterminate { ... }