I have a State in Context with Object. I am running a async
function in the useEffect
and passing my object state as dependency
.
I passed the state object as dependency because i want to re-render the component when values of
settings
object changes.
But it causes an infinite loop.
Update:
Let me clear my question more.
In my useEffect
, I am calling my async function addTextItem()
which calls the function finalPrice
and it updates the state, but this way it causes infinite loop.
On other hand, If i call finalPrice
in the useEffect
directly instead of calling addTextItem
then there is no infinite loop but it is also updating the state, right? then how this could be. & I need a solution as i have tried everything and now totally stuck.
Here is the code:
export default function CustomizerState(props) {
const initialText = "Hello"
const initialSize = {
x: REACT_APP_SIZE_X,
y: REACT_APP_SIZE_Y
}
const initialTextItem = {
id: generateID(),
text: "Hello",
font: fonts[0].value,
size: initialSize,
color: colors[0],
backplate: "cut-sharp",
uvPrint: false,
quantity: 1,
neonPrice: 0,
backplatePrice: 0,
neonPower: 0,
totalPrice: 0
}
const [settings, setSettings] = useState({
textItems: [],
libraryItems: [],
ownDesigns: [],
accessories: [
// My Objects here
],
finalPrice: 0
})
const addTextItem = async () => {
const pathLength = await textToPath(initialText, initialSize.x)
const { backplatePrice, neonPrice, neonPower, totalPrice } = calculateSvgPrice(pathLength)
const id = generateID()
const newItems = [
...settings.textItems,
{...initialTextItem, id, backplatePrice, neonPrice, neonPower, totalPrice}
]
finalPrice("textItems", newItems)
}
const finalPrice = (itemType = null, items = null) => {
const textItemsPrice = getTotalPrice()
const libraryItemsPrice = getTotalPrice("libraryItems")
const accessoriesPrice = getTotalPrice("accessories", "unitPrice")
const finalPrice = textItemsPrice + libraryItemsPrice + parseInt(accessoriesPrice)
if (itemType === null) {
setSettings((prevState) => (
{...prevState, finalPrice}
))
return false
}
setSettings((prevState) => (
{...prevState, [itemType]: items, finalPrice}
))
}
useEffect(() => {
// It will add first initial form item
addTextItem()
}, [JSON.stringify(settings)])
return (
<CustomizerContext.Provider value={{settings, addTextItem}}>
{props.children}
</CustomizerContext.Provider>
)
}
I have google and tried the solutions, but nothing worked for me. Can someone help me to fix this issue? I am stuck....
I forgot that when re-rendering happens, it also runs useEffect
obviously and it causes setState
again and again.
I managed to fix this by creating a state named initialItemCount
with 0
initial value. I am checking if that state value is 0 then run addTextItem
which will add my initial form item and updates the final price, but if the value 1 then only run the finalPrice
function.
const [initialItemCount, setInitialItemCount] = useState(0)
useEffect(() => {
if (initialItemCount === 0) {
addTextItem()
setInitialItemCount(1)
}
if (initialItemCount === 1) {
finalPrice()
}
}, [JSON.stringify(settings)])
Finally, inner peace.