我如何管理反应 js 中每一行的状态?
How do I manage the state of each row in react js?
我正在将数据库中的数据映射到 html table,其中每一行都有一个切换按钮来标记它们是否存在。但是我不确定如何保存每行切换按钮的状态,因为它们都会有所不同。
function Component() {
const [students, setStudents] = useState([]);
const [absent, setAbsent] = useState(false);
const updateAbsent = () => {
console.log(absent);
};
return (
<div className="attendance-today-container">
<h1>Daily attendance</h1>
<table ref={table}>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Absent?</th>
</tr>
{students.map((student, i) => {
return (
<tr>
<td key={i}>{student.firstName}</td>
<td>{student.lastName}</td>
<td>
<label class="switch">
<input
type="checkbox"
onClick={() => {
setAbsent(!absent);
}}
/>
<span class="slider round"></span>
</label>
</td>
</tr>
);
})}
</table>
<button onClick={updateAbsent}>Send</button>
</div>
);
}
一种简单的方法是存储学生数据,以及他们是否存在于同一状态。
每个学生都可以有一个id,方便识别。一个函数可以遍历学生状态数组并使用 id 标识哪个学生被标记为缺席或在场。
const data = [
{ id: 1, firstName: 'John', lastName: 'Doe', absent: false },
{ id: 2, firstName: 'Jane', lastName: 'Doe', absent: false },
];
const StudentList = () => {
const [students, setStudents] = useState(data);
const updateAbsent = () => {
const absents = students.filter((student) => student.absent === true);
console.log(absents);
};
const handleToggleAbsent = (toggleStudent) => {
setStudents((prevStudents) =>
prevStudents.map((student) => {
if (student.id !== toggleStudent.id) return student;
return { ...student, absent: !student.absent };
})
);
};
return (
<div className="attendance-today-container">
<h1>Daily attendance</h1>
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Absent?</th>
</tr>
</thead>
<tbody>
{students.map((student) => {
return (
<StudentItem
student={student}
key={student.id}
onToggleAbsent={handleToggleAbsent}
/>
);
})}
</tbody>
</table>
<button onClick={updateAbsent}>Send</button>
</div>
);
};
const StudentItem = (props) => {
const { student, onToggleAbsent } = props;
return (
<tr>
<td>{student.firstName}</td>
<td>{student.lastName}</td>
<td>
<label className="switch">
<input
type="checkbox"
onClick={onToggleAbsent.bind(null, student)}
/>
<span className="slider round"></span>
</label>
</td>
</tr>
);
};
export default StudentList;
这个概念与 Sheik Yerbouti 所建议的和 SamiElk 所展示的一致。
获取学生对象数组,并为每个对象添加一个名为absent
的属性,并将其默认设置为false
。然后让相应的复选框根据数组中对象的索引及其 absent
属性 的当前值为每个学生正确切换 absent
。我创建了一个名为 getData
的函数,它将模拟您的 API 调用以获取学生数据。这是代码:
import { useEffect, useState } from "react";
import "./styles.css";
const getData = () => {
return new Promise(resolve => {
resolve([{firstName: "John", lastName: "Marks"}, {firstName: "Garry", lastName: "Nelson"}]);
})
}
export default function App() {
const [students, setStudents] = useState([]);
const markAbsent = (i) => {
setStudents(prev =>
prev.map((s, index) => ({...s, absent: i === index ? !s.absent : s.absent}))
)
}
useEffect(() => {
getData()
.then(data => {
data = data.map(i => ({absent: false, ...i}));
setStudents(data);
})
}, [])
return (
<div className="attendance-today-container">
<h1>Daily attendance</h1>
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Absent?</th>
</tr>
{students.map((student, i) => {
return (
<tr>
<td key={i}>{student.firstName}</td>
<td>{student.lastName}</td>
<td>
<label class="switch">
<input
type="checkbox"
defaultChecked={student.absent}
onClick={() => markAbsent(i)}
/>
<span className="slider round"></span>
</label>
</td>
</tr>
);
})}
</table>
<button onClick={() => false}>Send</button>
</div>
);
}
请注意,我不确定 Send
按钮应该做什么,所以我离开了它 non-functional。这里有一个Sandbox link给你玩。
我正在将数据库中的数据映射到 html table,其中每一行都有一个切换按钮来标记它们是否存在。但是我不确定如何保存每行切换按钮的状态,因为它们都会有所不同。
function Component() {
const [students, setStudents] = useState([]);
const [absent, setAbsent] = useState(false);
const updateAbsent = () => {
console.log(absent);
};
return (
<div className="attendance-today-container">
<h1>Daily attendance</h1>
<table ref={table}>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Absent?</th>
</tr>
{students.map((student, i) => {
return (
<tr>
<td key={i}>{student.firstName}</td>
<td>{student.lastName}</td>
<td>
<label class="switch">
<input
type="checkbox"
onClick={() => {
setAbsent(!absent);
}}
/>
<span class="slider round"></span>
</label>
</td>
</tr>
);
})}
</table>
<button onClick={updateAbsent}>Send</button>
</div>
);
}
一种简单的方法是存储学生数据,以及他们是否存在于同一状态。
每个学生都可以有一个id,方便识别。一个函数可以遍历学生状态数组并使用 id 标识哪个学生被标记为缺席或在场。
const data = [
{ id: 1, firstName: 'John', lastName: 'Doe', absent: false },
{ id: 2, firstName: 'Jane', lastName: 'Doe', absent: false },
];
const StudentList = () => {
const [students, setStudents] = useState(data);
const updateAbsent = () => {
const absents = students.filter((student) => student.absent === true);
console.log(absents);
};
const handleToggleAbsent = (toggleStudent) => {
setStudents((prevStudents) =>
prevStudents.map((student) => {
if (student.id !== toggleStudent.id) return student;
return { ...student, absent: !student.absent };
})
);
};
return (
<div className="attendance-today-container">
<h1>Daily attendance</h1>
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Absent?</th>
</tr>
</thead>
<tbody>
{students.map((student) => {
return (
<StudentItem
student={student}
key={student.id}
onToggleAbsent={handleToggleAbsent}
/>
);
})}
</tbody>
</table>
<button onClick={updateAbsent}>Send</button>
</div>
);
};
const StudentItem = (props) => {
const { student, onToggleAbsent } = props;
return (
<tr>
<td>{student.firstName}</td>
<td>{student.lastName}</td>
<td>
<label className="switch">
<input
type="checkbox"
onClick={onToggleAbsent.bind(null, student)}
/>
<span className="slider round"></span>
</label>
</td>
</tr>
);
};
export default StudentList;
这个概念与 Sheik Yerbouti 所建议的和 SamiElk 所展示的一致。
获取学生对象数组,并为每个对象添加一个名为absent
的属性,并将其默认设置为false
。然后让相应的复选框根据数组中对象的索引及其 absent
属性 的当前值为每个学生正确切换 absent
。我创建了一个名为 getData
的函数,它将模拟您的 API 调用以获取学生数据。这是代码:
import { useEffect, useState } from "react";
import "./styles.css";
const getData = () => {
return new Promise(resolve => {
resolve([{firstName: "John", lastName: "Marks"}, {firstName: "Garry", lastName: "Nelson"}]);
})
}
export default function App() {
const [students, setStudents] = useState([]);
const markAbsent = (i) => {
setStudents(prev =>
prev.map((s, index) => ({...s, absent: i === index ? !s.absent : s.absent}))
)
}
useEffect(() => {
getData()
.then(data => {
data = data.map(i => ({absent: false, ...i}));
setStudents(data);
})
}, [])
return (
<div className="attendance-today-container">
<h1>Daily attendance</h1>
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Absent?</th>
</tr>
{students.map((student, i) => {
return (
<tr>
<td key={i}>{student.firstName}</td>
<td>{student.lastName}</td>
<td>
<label class="switch">
<input
type="checkbox"
defaultChecked={student.absent}
onClick={() => markAbsent(i)}
/>
<span className="slider round"></span>
</label>
</td>
</tr>
);
})}
</table>
<button onClick={() => false}>Send</button>
</div>
);
}
请注意,我不确定 Send
按钮应该做什么,所以我离开了它 non-functional。这里有一个Sandbox link给你玩。