I'm new to React and need some help.
I came across the concept of useEffect so I started to implement it in my small webapp. I want to calculate the price according a changing value in my formData
object. If formData.koerper
changes it triggers first the setFormData
function and then updateK
which I further use to trigger useEffect. setFormData
and updateK
are inside the handleKoerper
function. The code is as following:
import React, { useState, useEffect, useRef } from 'react'
import { Form } from 'react-bootstrap'
import './Forms.css'
function PictureCustomization({ formData, setFormData }) {
const settingPrice = () => {
if (formData.koerper === "Ganzkörper") {
let calc = formData.preis + 10
setFormData({...formData, preis: calc})
} else {
let calc = formData.preis - 10
setFormData({...formData, preis: calc})
}
}
const [updatedK, setUpdatedK] = useState(0)
const isFirstRun = useRef(true)
const handleKoerper = (event) => {
setFormData({...formData, koerper: event.target.value})
let newUpdate = updatedK + 1
setUpdatedK(newUpdate)
console.log(newUpdate)
}
const handleHandgemalt = (event) => {
if (event.target.checked){
setFormData({ ...formData, handgemalt: event.target.checked })
} else {
setFormData({ ...formData, handgemalt: event.target.checked, format: 'Digital' })
}
}
useEffect( () => {
if (isFirstRun.current) {
isFirstRun.current = false;
} else {
settingPrice()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [updatedK])
return (
<div>
<div className="form-title">Bild Personalisieren</div>
<Form>
<Form.Group controlId='formKoerper'>
<Form.Label className="form-label">Körperoption</Form.Label>
<Form.Select
value={formData.koerper}
onChange={ handleKoerper }>
<option value="Ganzkörper">Ganzkörper</option>
<option value="Halbkörper">Halbkörper</option>
</Form.Select>
</Form.Group>
<h2>{formData.koerper}</h2>
<Form.Group controlId='formAura'>
<Form.Label className="form-label"></Form.Label>
<Form.Check
className="form-label-checkbox"
type="checkbox"
label="Soll das Bild eine Aura enthalten?"
checked={formData.aura}
onChange={(event) => setFormData({ ...formData, aura: event.target.checked })}
/>
</Form.Group>
<Form.Group controlId='formHintergrund'>
<Form.Label className="form-label"></Form.Label>
<Form.Check
className="form-label-checkbox"
type="checkbox"
label="Soll das Bild ein Hintergrund haben? Standard Hintergrund ist weiss."
checked={formData.hintergrund}
onChange={(event) => setFormData({ ...formData, hintergrund: event.target.checked })}
/>
</Form.Group>
<Form.Group controlId='formHandgemalt'>
<Form.Label className="form-label"></Form.Label>
<Form.Check
className="form-label-checkbox"
type="checkbox"
label="Soll das Bild handgemalt sein?"
checked={formData.handgemalt}
onChange={ handleHandgemalt }
/>
</Form.Group>
<Form.Group controlId='formLieferung'>
<h6 className='form-info-message'>Falls Sie die Option "handgemalt" ausgewählt haben, bitte ich Sie das Format des Bildes auszuwählen. Wenn die Option "handgemalt" nicht aktiv ist, wird die Zeichnung nur digital per E-Mail zugestellt. Das digitale Format ist 320x320 Pixel</h6>
<Form.Select aria-label="Default select example"
disabled={formData.handgemalt ? false : true}
value={formData.format}
onChange={(event) => setFormData({ ...formData, format: event.target.value })}>
<option value="">Wähle eine Option</option>
<option value="A4">A4</option>
<option value="A3">A3</option>
</Form.Select>
</Form.Group>
<Form.Group controlId="formEmail">
<Form.Label className="form-label">Was möchtest du mir noch sagen?</Form.Label>
<Form.Control
type="text"
placeholder="Bemerkungen"
value={formData.bemerkungen}
as="textarea"
style={{ height: '100px' }}
onChange={(event) => setFormData({ ...formData, bemerkungen: event.target.value })} />
</Form.Group>
</Form>
</div>
)
}
export default PictureCustomization
If I don't include // eslint-disable-next-line react-hooks/exhaustive-deps
in my useEffect
there will be a warning message which tells me to include settingPrice
in my dependencies. If I include settingPrice
in my dependencies, useEffect will start an infinite loop which makes sense to me since I'm triggering settingPrice
over and over again. So, my question is: Is there something I can change to not bypass the eslint rule? Bypassing the rule just feels wrong to me.
Also, I know I could put setFormData
in my useEffect
and therefore not use a seperate function but that would lead me to the same problem anyway.