#reactjs #if-statement #use-state
Вопрос:
Я пытаюсь установить переменную «список» в операторе «если», а затем обновить свои данные с помощью useState, но если я напишу setData вне оператора «если», это покажет, что переменная «список» не определена, поэтому я должен переписать весь код внутри оператора «если» и «еще» (что нежелательно).
const [data, setData] = useState({
name: "",
email: "",
machinetype: [],
});
const handleInputChange = (event) => {
if (event.target.name === "machinetype") {
const chck = event.target.checked;
if (chck) {
const list = data[event.target.name].concat([event.target.value]);
} else {
const index = data[event.target.name].indexOf(event.target.value);
const remove = data[event.target.name].splice(index, 1);
const list = data[event.target.name];
}
setData({
...data,
[event.target.name]: list,
});
}
};
Какие-нибудь советы? Спасибо
Комментарии:
1. Переменные Const ограничены областью их непосредственного окружения { } фигурными скобками и не могут быть доступны во внешней лексической области. Определите переменную над блоком if с помощью » let » вместо этого
Ответ №1:
переменные, объявленные в операторах if, остаются в пределах области действия оператора if. Поэтому, когда указатель покидает блок if, переменная удаляется.
все, что вам нужно сделать, это следующее
const [data, setData] = useState({
name: "",
email: "",
machinetype: [],
});
const handleInputChange = (event) => {
if (event.target.name === "machinetype") {
const chck = event.target.checked;
let list = null;
if (chck) {
list = data[event.target.name].concat([event.target.value]);
} else {
const index = data[event.target.name].indexOf(event.target.value);
const remove = data[event.target.name].splice(index, 1);
list = data[event.target.name];
}
setData({
...data,
[event.target.name]: list,
});
}
};
Ответ №2:
Переместите объявление list
за пределы ifs.
Вы также захотите убедиться, что вы не изменяете список внутренне, не копируя его, так что в целом что-то вроде
const [data, setData] = useState({
name: "",
email: "",
machinetype: [],
});
const handleInputChange = (event) => {
const {name} = event.target;
if (name !== "machinetype") { // early return to make the function shallower
return;
}
const list = [...data[name]]; // shallow copy
if (event.target.checked) {
list.push(event.target.value);
} else {
const index = list.indexOf(event.target.value);
list.splice(index, 1);
}
setData({
...data,
[name]: list,
});
};
должно сработать.
Ответ №3:
В то время как вы можете объявить list
об этом заранее с let
помощью …
if (event.target.name === "machinetype"){
const chck = event.target.checked
let list;
// assign to list...
Более правильным подходом ИМО было бы объединить эти две возможности в единое выражение.
if (!chck) {
// this block doesn't make much sense though
const index = data[event.target.name].indexOf(event.target.value);
const remove = data[event.target.name].splice(index, 1);
}
const list = data[event.target.name].concat(chck ? [event.target.value] : []);
setData({
...data,
[event.target.name]: list,
});
Но присвоение неиспользуемой переменной remove
не имеет смысла, и мутация никогда не должна выполняться для состояния в React. Лучше сделать что-то вроде
const handleInputChange = ({ target }) => {
const { name, value, checked } = target;
if (name !== "machinetype") return;
if (checked) {
setData({
...data,
[name]: [...data[name], value],
});
} else {
setData({
...data,
[name]: data[name].filter(existingVal => existingVal !== value)
});
}
};
Комментарии:
1. Однако этого не хватает
.splice()
, чтобы удалить все из списка.