I'm at a loss. No idea whats happening. I have a zustand store set up. Using react router with vite. I'm not even sure why react router is throwing errors becuase this component im trying to finish has nothing to do with routes. If i add to the store with a setter function (below) i get an error in the browser console saying React Router caught the following error during render Error: Rendered more hooks than during the previous render.
However, if i remove from state i get the error React Router caught the following error during render Error: Rendered fewer hooks than expected. This may be caused by an accidental early return statement.
The errors are all pointing back to a specific component (below). If you need any other code just let me know.
//Setter function for state inside store
addIncome: (val: Income) => {
const current: Income[] = incomeStore.getState().currentIncome
const result: Income[] = [...current, val];
set(() => ({currentIncome: result}));
}
// Remove function for state inside store
removeIncome: (id: number) => {
const result = incomeStore.getState().currentIncome
const newInc = result.filter((x: Income) => x.id !== id)
set(() => ({currentIncome: newInc}));
}
The component that it mentioned in every error appears to have to do with the map of currentIncome?
import {useState} from 'react'
import Card from "~/components/tailwindcss/Card";
import useModifyData from "~/hooks/useModifyData";
import EditIncome from "~/components/income/EditIncome";
import SingleIncomeRender from "~/components/income/SingleIncomeRender";
import {useIncomeStore} from "~/state/incomeStore";
function IncomeRender() {
const currentIncome = useIncomeStore.use.currentIncome()
const renderIncome = useIncomeStore.use.renderIncome()
const removeIncomeFromState = useIncomeStore.use.removeIncome()
const colorOptions = {
title: "bg-green-700",
body: "bg-green-100",
text: "text-black",
border: "border-green-700"
}
const deleteData = (id: number) => {
useModifyData(id, "income", "delete")
removeIncomeFromState(id)
}
if (renderIncome) {
return (
<div>Loading....</div>
)
}
return (
<div className="grid grid-cols-2 gap-4 place-items-center mb-5">
{currentIncome.map((item, i) => {
const [edit, setEdit] = useState(false);
const options = {
id: item.id!,
setEditing: () => setEdit(!edit),
setDelete: (id: number) => deleteData(id),
edit: edit,
showEdit: true,
}
return (
<Card key={item.id} title={item.name} colorOptions={colorOptions} options={options}>
{edit ? <EditIncome id={item.id!} setEditing={() => setEdit(!edit)}/> : <SingleIncomeRender id={item.id!} edit={edit}/>}
</Card>
)
})}
</div>
)
}
export default IncomeRender
You cannot use useState
in a loop (or after an early return). Hooks need to be used at the top level of a component and unconditionally.
Try to extract the callback containing useState
to a separate component, and learn about the rules of hooks.