1

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.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Here's a bug report on github that explains why this happens and how to remove the warning: https://github.com/facebook/react/issues/20530. If you want to understand more on how useEffect works, this is the documentation: https://reactjs.org/docs/hooks-effect.html – Alex Varela Dec 16 '22 at 18:16
  • 1
    Does this answer your question? [How to fix missing dependency warning when using useEffect React Hook](https://stackoverflow.com/questions/55840294/how-to-fix-missing-dependency-warning-when-using-useeffect-react-hook) – Konrad Dec 16 '22 at 19:36

0 Answers0