如何切换位于来自 API 的另一个数组的每个对象内的数组的显示?
How can I toggle the display of an array that is located within each object of another array that comes from an API?
例如:
我正在向网站显示来自 API 的多个 Student
对象。每个 Student
对象都包含他们的测试数组 Grades
以及其他学生信息。现在,我想在屏幕上显示每个 Student
的信息,而不是显示学生的 Grades
,我希望每个 Student
都有一个 "+"
Button
这将切换学生 Grades
.
的显示
我正在使用 React 的 useState 挂钩。我的问题是,当我单击 "+"
Button
时,它会切换所有学生的成绩 on/off。我想要的是仅切换我单击其按钮的学生的 Grades
。
这是我的代码:
import axios from 'axios';
import { useState, useEffect } from 'react';
import styles from "./Home.module.css";
import { v4 as uuidv4 } from 'uuid';
const Home = () => {
const [students, setStudents] = useState([]);
const [filteredStudents, setFilteredStudents] = useState([]);
const [isShown, setIsShown] = useState(true);
const fetchStudents = async () => {
const response = await axios.get(`https://api.hatchways.io/assessment/students`);
setStudents(response.data.students);
setFilteredStudents(response.data.students);
console.log(response.data.students);
}
const findAverageGrade = arr => {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += parseInt(arr[i]);
}
return sum / arr.length;
}
const searchStudentName = async (searchName) => {
const searchNameFiltered = searchName.toLowerCase();
console.log(searchNameFiltered);
if (searchNameFiltered === "") {
fetchStudents();
return;
}
var newArray = await students.filter((student) => {
return student.firstName.toLowerCase().includes(searchNameFiltered)
|| student.lastName.toLowerCase().includes(searchNameFiltered);
})
await setFilteredStudents(newArray);
}
const toggleGrades = () => {
console.log("toggle");
}
useEffect(() => {
fetchStudents();
}, [])
return(
<>
<div>
<input type="text" placeholder="Search by name" onChange={(event) => searchStudentName(event.target.value) }/>
{filteredStudents.map((student) => (
<div key={student.email} className={styles.studentItem}>
<img className={styles.studentImage} src={student.pic} />
<div className={styles.studentInfoContainer}>
<div className={styles.studentHeader}>
<p className={styles.studentName}>{student.firstName} {student.lastName}</p>
</div>
<ul className={styles.studentDetail}>
<li>Email: {student.email}</li>
<li>Company: {student.company}</li>
<li>Skill: {student.skill}</li>
<li>Average: {findAverageGrade(student.grades)}%</li>
<button onClick={() => {
setIsShown(!isShown);
}}>
+
</button>
{isShown ? <div>
<table className={styles.gradesTable}>
<tbody>
{student.grades.map((grade) => (
<tr key={uuidv4()}>
<td>Test</td>
<td>{grade}%</td>
</tr>
))}
</tbody>
</table>
</div>
: null }
</ul>
</div>
</div>
)
)}
</div>
</>
)
}
export default Home;
只需将映射部分移除到另一个组件并在映射部分中导入即可。通过这种方式,您将拥有相同的结构,并且无需任何额外逻辑即可工作
新组件
const Students = ({student}) => {
const [isShown, setIsShown] = useState(true);
return (
<div key={student.email} className={styles.studentItem}>
<img className={styles.studentImage} src={student.pic} />
<div className={styles.studentInfoContainer}>
<div className={styles.studentHeader}>
<p className={styles.studentName}>{student.firstName} {student.lastName}</p>
</div>
<ul className={styles.studentDetail}>
<li>Email: {student.email}</li>
<li>Company: {student.company}</li>
<li>Skill: {student.skill}</li>
<li>Average: {findAverageGrade(student.grades)}%</li>
<button onClick={() => {
setIsShown(!isShown);
}}>
+
</button>
{isShown ? <div>
<table className={styles.gradesTable}>
<tbody>
{student.grades.map((grade) => (
<tr key={uuidv4()}>
<td>Test</td>
<td>{grade}%</td>
</tr>
))}
</tbody>
</table>
</div>
: null }
</ul>
</div>
</div>
)
}
主页组件
import axios from 'axios';
import { useState, useEffect } from 'react';
import styles from "./Home.module.css";
import { v4 as uuidv4 } from 'uuid';
const Home = () => {
const [students, setStudents] = useState([]);
const [filteredStudents, setFilteredStudents] = useState([]);
const fetchStudents = async () => {
const response = await axios.get(`https://api.hatchways.io/assessment/students`);
setStudents(response.data.students);
setFilteredStudents(response.data.students);
console.log(response.data.students);
}
const findAverageGrade = arr => {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += parseInt(arr[i]);
}
return sum / arr.length;
}
const searchStudentName = async (searchName) => {
const searchNameFiltered = searchName.toLowerCase();
console.log(searchNameFiltered);
if (searchNameFiltered === "") {
fetchStudents();
return;
}
var newArray = await students.filter((student) => {
return student.firstName.toLowerCase().includes(searchNameFiltered)
|| student.lastName.toLowerCase().includes(searchNameFiltered);
})
await setFilteredStudents(newArray);
}
const toggleGrades = () => {
console.log("toggle");
}
useEffect(() => {
fetchStudents();
}, [])
return(
<>
<div>
<input type="text" placeholder="Search by name" onChange={(event) => searchStudentName(event.target.value) }/>
{filteredStudents.map((student) => (
<Student student={student} />
)
)}
</div>
</>
)
}
export default Home;
注意:我没有包括组件的导出导入部分 css 但这是简单的部分
例如:
我正在向网站显示来自 API 的多个 Student
对象。每个 Student
对象都包含他们的测试数组 Grades
以及其他学生信息。现在,我想在屏幕上显示每个 Student
的信息,而不是显示学生的 Grades
,我希望每个 Student
都有一个 "+"
Button
这将切换学生 Grades
.
我正在使用 React 的 useState 挂钩。我的问题是,当我单击 "+"
Button
时,它会切换所有学生的成绩 on/off。我想要的是仅切换我单击其按钮的学生的 Grades
。
这是我的代码:
import axios from 'axios';
import { useState, useEffect } from 'react';
import styles from "./Home.module.css";
import { v4 as uuidv4 } from 'uuid';
const Home = () => {
const [students, setStudents] = useState([]);
const [filteredStudents, setFilteredStudents] = useState([]);
const [isShown, setIsShown] = useState(true);
const fetchStudents = async () => {
const response = await axios.get(`https://api.hatchways.io/assessment/students`);
setStudents(response.data.students);
setFilteredStudents(response.data.students);
console.log(response.data.students);
}
const findAverageGrade = arr => {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += parseInt(arr[i]);
}
return sum / arr.length;
}
const searchStudentName = async (searchName) => {
const searchNameFiltered = searchName.toLowerCase();
console.log(searchNameFiltered);
if (searchNameFiltered === "") {
fetchStudents();
return;
}
var newArray = await students.filter((student) => {
return student.firstName.toLowerCase().includes(searchNameFiltered)
|| student.lastName.toLowerCase().includes(searchNameFiltered);
})
await setFilteredStudents(newArray);
}
const toggleGrades = () => {
console.log("toggle");
}
useEffect(() => {
fetchStudents();
}, [])
return(
<>
<div>
<input type="text" placeholder="Search by name" onChange={(event) => searchStudentName(event.target.value) }/>
{filteredStudents.map((student) => (
<div key={student.email} className={styles.studentItem}>
<img className={styles.studentImage} src={student.pic} />
<div className={styles.studentInfoContainer}>
<div className={styles.studentHeader}>
<p className={styles.studentName}>{student.firstName} {student.lastName}</p>
</div>
<ul className={styles.studentDetail}>
<li>Email: {student.email}</li>
<li>Company: {student.company}</li>
<li>Skill: {student.skill}</li>
<li>Average: {findAverageGrade(student.grades)}%</li>
<button onClick={() => {
setIsShown(!isShown);
}}>
+
</button>
{isShown ? <div>
<table className={styles.gradesTable}>
<tbody>
{student.grades.map((grade) => (
<tr key={uuidv4()}>
<td>Test</td>
<td>{grade}%</td>
</tr>
))}
</tbody>
</table>
</div>
: null }
</ul>
</div>
</div>
)
)}
</div>
</>
)
}
export default Home;
只需将映射部分移除到另一个组件并在映射部分中导入即可。通过这种方式,您将拥有相同的结构,并且无需任何额外逻辑即可工作
新组件
const Students = ({student}) => {
const [isShown, setIsShown] = useState(true);
return (
<div key={student.email} className={styles.studentItem}>
<img className={styles.studentImage} src={student.pic} />
<div className={styles.studentInfoContainer}>
<div className={styles.studentHeader}>
<p className={styles.studentName}>{student.firstName} {student.lastName}</p>
</div>
<ul className={styles.studentDetail}>
<li>Email: {student.email}</li>
<li>Company: {student.company}</li>
<li>Skill: {student.skill}</li>
<li>Average: {findAverageGrade(student.grades)}%</li>
<button onClick={() => {
setIsShown(!isShown);
}}>
+
</button>
{isShown ? <div>
<table className={styles.gradesTable}>
<tbody>
{student.grades.map((grade) => (
<tr key={uuidv4()}>
<td>Test</td>
<td>{grade}%</td>
</tr>
))}
</tbody>
</table>
</div>
: null }
</ul>
</div>
</div>
)
}
主页组件
import axios from 'axios';
import { useState, useEffect } from 'react';
import styles from "./Home.module.css";
import { v4 as uuidv4 } from 'uuid';
const Home = () => {
const [students, setStudents] = useState([]);
const [filteredStudents, setFilteredStudents] = useState([]);
const fetchStudents = async () => {
const response = await axios.get(`https://api.hatchways.io/assessment/students`);
setStudents(response.data.students);
setFilteredStudents(response.data.students);
console.log(response.data.students);
}
const findAverageGrade = arr => {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += parseInt(arr[i]);
}
return sum / arr.length;
}
const searchStudentName = async (searchName) => {
const searchNameFiltered = searchName.toLowerCase();
console.log(searchNameFiltered);
if (searchNameFiltered === "") {
fetchStudents();
return;
}
var newArray = await students.filter((student) => {
return student.firstName.toLowerCase().includes(searchNameFiltered)
|| student.lastName.toLowerCase().includes(searchNameFiltered);
})
await setFilteredStudents(newArray);
}
const toggleGrades = () => {
console.log("toggle");
}
useEffect(() => {
fetchStudents();
}, [])
return(
<>
<div>
<input type="text" placeholder="Search by name" onChange={(event) => searchStudentName(event.target.value) }/>
{filteredStudents.map((student) => (
<Student student={student} />
)
)}
</div>
</>
)
}
export default Home;
注意:我没有包括组件的导出导入部分 css 但这是简单的部分