0

I have a form on a React app that lets users create a blog post. Part of this form has users select a "fire level" 1 through 5 by clicking on an icon in a row of icons. If they select the first icon, I want to set the formState.fireLevel to 1, if they click the fifth icon, I want to set formState.fireLevel to 5. For some reason when I console log the fireLevel after an icon is clicked, it logs the previous fire level that was set BEFORE the click. So on the first time I handle the form, if I click fire level 5, it logs "undefined". Then if I click fire level 4, it console logs "5". Then I select another one, it console logs 4, and so on. It's like the fireLevel is one click behind where it should be. Can someone help me figure out why this is happening?

Here is my JSX, the function that is supposed to set the formState.fireLevel is called handleFireIconClick(e), and it simply sets the fireLevel to the id of the icon thats clicked.

import React from 'react'
import fireIconImage from '../images/fireIcon.png'
import FireIcon from './FireIcon'


export default function BlogPostForm () {
    const [formState, setFormState] = React.useState({ flaire: '', title: '', text: '', fireLevel: ''});
    const [isHovered, setIsHovered] = React.useState();
    const [isLit, setIsLit] = React.useState();

    function changeFlaire(event) {
        const selectedFlaire = event.target.value;
        setFormState( {...formState, flaire: selectedFlaire });
    }

    function changeTitle(event) {
        const title = event.target.value;
        setFormState( {...formState, title: title });
    }

    function changeText(event) {
        const text = event.target.value;
        setFormState( {...formState, text: text });
    }

    function handleMouseOver(e) {
        setIsHovered(e.target.id);
    }

    function handleMouseLeave(e) {
        setIsHovered();
    }

    function handleFireIconClick(e) {
        setIsLit(e.target.id);
        setFormState( {...formState, fireLevel: e.target.id});
        console.log(formState)
        
    }


    function handleFireIconClass(fireLevel) {
        const classNames = ['fireIcon']
            classNames.push(`fireIcon${fireLevel}`)
            if (isHovered >= fireLevel) {
                classNames.push('isHeld')
            }
            if (isLit >= fireLevel) {
                classNames.push('isLit')
            }
        return classNames.join(' ');
        
    }

    function submitForm(event) {
        event.preventDefault();
        const data = formState;
        const options = {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        }
        fetch('http://localhost:8000', options);
    }




    const fireIconsArray = [];

    for (let i = 0; i < 5; i++) {
        fireIconsArray.push(
            <FireIcon 
                onClick={handleFireIconClick}
                onMouseLeave={handleMouseLeave}
                onMouseOver={handleMouseOver}
                className={handleFireIconClass(i+1)}
                src={fireIconImage}
                alt="fire icon"
                id={i+1}
                key={i+1}
            />
        )
    }

    
    return (
        <form className="postForm">
            <h1 className="postFormHeader">Create a blog post!</h1>        
                <select
                    required
                    className="flaireSelect" 
                    value={formState.flaire}
                    onChange={changeFlaire}>
                        <option disabled={true} value="">Choose a flaire</option>
                        <option value="JavaScript">JavaScript</option>
                        <option value="CSS">CSS</option>
                        <option value="HTML">HTML</option>
                        <option value="REACT">REACT</option>
                        <option value="BACKEND">BACKEND</option>
                </select>
                <input
                    value={formState.title}
                    onChange={changeTitle}
                    className="titleBox"
                    placeholder="title"
                    type="text"
                    id="title"
                    name="title"
                />
                <textarea
                    value={formState.text}
                    onChange={changeText}
                    className="textBox"
                    placeholder="text"
                    type="text"
                    id="blogPost"
                    name="blogPost"
                />
                <div className="fireIconContainer">
                    {fireIconsArray}
                </div>  
                <div className="blogPostFormButtonContainer">
                    <button className="blogPostSubmit" type="submit" onClick={submitForm}>SUBMIT</button>
                    <button className="blogPostCancel" type="submit">CANCEL</button>
                </div>

        </form>
    )
}
Nick Johnson
  • 135
  • 7
  • 3
    Does this answer your question? [Why does calling react setState method not mutate the state immediately?](https://stackoverflow.com/questions/30782948/why-does-calling-react-setstate-method-not-mutate-the-state-immediately) also, when setting state and using the old state, you should use a callback, e.g. `setState(( prevState ) => ({...prevState, ...someOtherNewValues}))` – andy mccullough Oct 19 '22 at 15:17

0 Answers0