I'm trying to set a variable "list" in an "if" statement, and after that, update my data via useState, but if I write setData outside the "if" statement, it shows that the variable "list" is not defined, so I must rewrite all the code inside the "if" and the "else" statement (which is not desirable)
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,
});
}
};
Any advices? Thanks
CodePudding user response:
Move the declaration of list
outside the ifs.
You'll also want to make sure you're not internally modifying the list without copying it, so all in all something like
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,
});
};
should do the trick.
CodePudding user response:
variables declared within if statements stay within the scope of the if statement. So when the pointer leaves the if block the variable is disposed of.
all you need to do is the following
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,
});
}
};
CodePudding user response:
While you can declare list
ahead of time with let
...
if (event.target.name === "machinetype"){
const chck = event.target.checked
let list;
// assign to list...
A nicer approach IMO would be to consolidate the two possibilities into a single expression.
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,
});
But the assignment to unused variable remove
doesn't make sense, and mutation should never be done to state in React. Better to do something like
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)
});
}
};