#javascript #reactjs
Вопрос:
Вот мой код. Я получаю данные студента из резервной копии, фильтрую их. Я не могу установить значение по умолчанию для параметра select, и ни setAssignedStudent
один из них не работает в консоли, которую я получаю undefined
. Пожалуйста, дайте мне знать, как это исправить.
//here is sample of students array
// let students- [ {name: "abc", email:"abc.com", mentor:"" },
// {name: "abc", email:"abc.com", mentor:"cda" }, {name: "abc", email:"abc.com", //mentor:"" }]
useEffect(() => {
const getStudents = async () => {
try {
const res = await fetch("http://localhost:3001/students");
const data = await res.json();
//console.log(data);
//filtering students based on who doesn;t have mentor
let filter = data.filter((e) => {
return e.mentor === "";
});
if (filter.length > 0) setStudents(filter);
} catch (err) {
console.log(err);
}
};
getStudents();
}, []);
const [assignedStudent, setAssignedStudent] = useState(students[1]);
const handleChange = (e) => {
setAssignedStudent(
students.find((student) => student._id == e.target.value)
);
console.log(assignedStudent);
};
const handleSubmit = async (e) => {
e.preventDefault();
console.log(assignedStudent);
}
<form onSubmit={(e) => handleSubmit(e)}>
<select onChange={handleChange} value={assignedStudent}>
{students.map((student) => {
return (
<>
<option key={student._id} value={student.id}>
{student.name}
</option>
</>
);
})}
</select>
<button type="submit">Submit </button>
</form>
Ответ №1:
Проблема:
ваш объект students пуст до вызова API и не был инициализирован в вашем setState
. таким образом, использование students.map
в вашем select
элементе приведет к ошибке (так как вы не можете отобразить через неопределенный массив).
Решение:
Перед использованием map
с arrayes есть две важные вещи:
- проверьте определение массива (определен ли и существует ли массив?)
- проверьте его длину (есть ли в массиве какое-то содержимое?)
Первый
проверьте его объявление/определение с помощью простого if
утверждения:
{
if(myArrayOfData) {
myArrayOfData.map(
// rest of the codes ...
)
}
}
Или с использованием ?
сокращенных if
{
myArrayOfData?.map(
// rest of the codes ...
)
}
Второй
проверьте содержимое массива и используйте map
функцию после проверки его длины (которая сообщает вам, что данные поступили из вызова API и т.д. и готовы к обработке).
{
if(myArrayOfData) {
if(myArrayOfData.length > 0) {
myArrayOfData.map(
// rest of the codes ...
)
}
}
}
Окончательно:
хотя приведенный выше фрагмент работает правильно, вы можете упростить его, проверив оба if
условия вместе:
{
if(myArrayOfData?.length > 0) {
myArrayOfData.map(
// rest of the codes ...
)
}
}
Необязательный:
В реальных примерах вам может потребоваться показать некоторые загружаемые компоненты во время извлечения данных.
{
if(myArrayOfData?.length > 0) {
myArrayOfData.map(
// rest of the codes ...
)
} else {
<Loading />
}
}
знать
const anEmptyArray = []
if(anEmptyArray){
// rest of the codes ...
}
Результат сравнения if(anEmptyArray)
всегда true
с пустым массивом.
Ответ №2:
Значение параметра должно быть _id. В вашей находке вы сравниваете с student._id
, но в опции значение, которое вы передали, является student.id
, поэтому find возвращает неопределенное
<option key={student._id} value={student._id}
{student.name}
</option>
Комментарии:
1. Я думал, что проблема в _id? @Zed