Reputation: 1829
I have this error that says everytime I'll submit it:
TypeError: s.indexOf is not a function
import React, { useState } from "react";
const checkboxes = [
{ id: 1, text: "Checkbox 1" },
{ id: 2, text: "Checkbox 2" },
{ id: 3, text: "Checkbox 3" }
];
const SearchResults = () => {
const [selectedCheckbox, setSelectedCheckbox] = useState([]);
const handleChange = (id) => {
const findIdx = selectedCheckbox.indexOf(id);
if (findIdx > -1) {
selectedCheckbox.splice(findIdx, 1);
} else {
selectedCheckbox.push(id);
}
setSelectedCheckbox(selectedCheckbox);
};
const handleSubmit = (e) => {
e.preventDefault();
console.log(JSON.stringify(selectedCheckbox));
try {
const userRef = db.collection("users").doc(uid);
const ref = userRef.set({
selectedCheckbox
});
console.log("done")
} catch (err) {
console.log(err);
}
};
return (
<div>
<div className="App">
<form onSubmit={handleSubmit}>
{checkboxes.map((checkbox) => (
<label key={checkbox.id}>
{checkbox.text}
<input
type="checkbox"
onChange={() => handleChange(checkbox.text)}
selected={selectedCheckbox.includes(checkbox.id)}
/>
</label>
))}
<button type="submit">Submit</button>
</form>
</div>
<p>Selected checkboxes: {JSON.stringify(selectedCheckbox)}</p>
</div>
);
};
This is the codesandbox, though there's not Firestore data here: https://codesandbox.io/s/handle-multiple-checkboxes-in-react-forked-xehxf?file=/src/App.js:0-2520
Any help would be appreciated. Thank you.
Upvotes: 0
Views: 308
Reputation: 16374
I suspect the error rises when your tracking array of selectedCheckbox
es goes undefined
even though this is not quite the case in the linked code sandbox.
In React as a general rule, you should never mutate the state even using React hooks which is you case in the handleChange
method.
You should update you event handler method as follows (always making a copy of the state array to construct a the new one):
const handleChange = (id) => {
const findIdx = selectedCheckbox.indexOf(id);
let selected;
if (findIdx > -1) {
selected = selectedCheckbox.filter((checkboxId) => checkboxId !== id);
} else {
selected = [...selectedCheckbox, id];
}
setSelectedCheckbox(selected);
};
You click event handler takes the checkbox id
as an argument and you should update you click handler accordingly:
<label key={checkbox.id}>
{checkbox.text}
<input
type="checkbox"
onChange={() => handleChange(checkbox.id)}
selected={selectedCheckbox.includes(checkbox.id)}
/>
</label>
Upvotes: 2