I have a variable that stores the index of a selected item. I used a conditional expression based on that variable to add/remove a class name so said item is rendered in a distinguishing way. I boiled down the problem to this snippet:
function App() {
const [selectedItem, setSelectedItem] = setState(-1);
setSelectedItem(0);
console.log(selectedItem);
return (
<>
{selectedItem !== 0 && <p>no item selected</p>}
{selectedItem === 0 && <p>item {selectedItem} selected</p>}
</>
);
}
This snippet always displays that no item is selected.
CodePudding user response:
The hook is called useState
, not setState
.
Calling setSelectedItem
inside the render function will trigger an infinite loop. You need to move it to an effect hook so it only runs one.
export default function App() {
const [selectedItem, setSelectedItem] = useState(-1);
useEffect(() => {
setSelectedItem(0);
}, []);
console.log(selectedItem);
return (
<>
{selectedItem !== 0 && <p>no item selected</p>}
{selectedItem === 0 && <p>item {selectedItem} selected</p>}
</>
);
}
CodePudding user response:
What is setState
? Do you mean useState
? And also, you shouldn't update the state like this, you should do it in a useEffect
, and use an empty array as dependency, so it will run only once, when your component is being mounted:
useEffect(() => {
setSelectedItem(0);
},[])
Then it is working like a charm
CodePudding user response:
Replace ===
and !==
with ==
and !=
, respectively, and voila, it works. Alas, a warning is reported that one shall use ===
instead.
selectedItem
is an array, apparently primitives make bad references. Still, it is bizarre to some extent that inside <p>
the variable is unboxed automatically, while for evaluating ===
it isn't and thus an array is compared to a primitive, which is not true, no matter the values. ==
compares every shit in JS that you feed it with, so here it works.
Hope, this saves somebody 2 hours of debugging.
If somebody has a correct workaround for this, please share below.