При изменении состояния в setDishes() ничего не происходит

Пишу интернет-магазин на React + Redux + Typescript и столкнулся вот с какой проблемой, для начала покажу код. Это модалка, которая добавляет блюдо в список блюд

interface AddDishModalProps {
    modal: boolean,
    setModal: React.Dispatch<boolean>,
}

const AddDishModal: FC<AddDishModalProps> = ({modal, setModal}) => {
    const dispatch = useDispatch()
    const dishes = useTypedSelector(state => state.dishes)
    const [infoModal, setInfoModal] = useState<boolean>(false)
    const [dish, setDish] = useState<IDish>(
        {id: 0, image: '', count: 0, price: 0, totalPrice: 0, title: '', description: '', category: ''}
    )

    const image = useInput('', {isEmpty: true})
    const category = useInput('', {isEmpty: true})
    const title = useInput('', {isEmpty: true})
    const description = useInput('', {isEmpty: true})
    const price = useInput('', {isEmpty: true})

    const addDishToMenu = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
        e.preventDefault()

        console.log(image.value)
        console.log(category.value)
        console.log(title.value)
        console.log(description.value)
        console.log(price.value)
        setDish({
            id: Date.now(),
            category: category.value,
            image: image.value,
            title: title.value,
            description: description.value,
            price: parseInt(price.value),
            count: 1,
            totalPrice: parseInt(price.value)})

        console.log(dish)
        dispatch(addDishAction(dish))

        setModal(false)
        setInfoModal(true)
        setTimeout(() => {
            setInfoModal(false)
        }, 2000)

        setDish({id: 0, image: '', count: 0, price: 0, totalPrice: 0, title: '', description: '', category: ''})
    }

    return (
        <div>
            <Modal activeWhenClicked={false} active={modal} setActive={setModal}>
                <div className={classes.text}>
                    Добавить <span> блюдо</span>
                </div>
                <form action='#'>
                    <div className={classes.modal_image}>
                        <ImageLoader image={image} dish={dish} setDish={setDish}/>
                    </div>
                    <div className={classes.modal_select}>
                        <div className={(category.isDirty && (category.isEmpty))
                            ? classes.incorrectData
                            : [classes.incorrectData, classes.hidden].join(' ')}>
                            Поле заполнено неверно
                        </div>
                        <label>Укажите категорию</label>
                        <div>
                            <Select
                                onBlur={(e) => {
                                    category.onBlurSelect(e)
                                }}
                                value={category.value}
                                onChange={(e) => {
                                    category.onChangeSelect(e)
                                }}
                                options={[
                                    {name: 'Еда', value: 'Еда'},
                                    {name: 'Напитки', value: 'Напитки'},
                                    {name: 'Закуски', value: 'Закуски'}
                                ]}
                                defaultValue={'Категория'}/>
                        </div>
                    </div>
                    <div className={classes.data}>
                        <div className={(title.isDirty && (title.isEmpty))
                            ? classes.incorrectData
                            : [classes.incorrectData, classes.hidden].join(' ')}>
                            Поле заполнено неверно
                        </div>
                        <label>Укажите название</label>
                        <input type='text' value={title.value}
                               onBlur={e => title.onBlur(e)}
                               onChange={e => title.onChange(e)}/>
                    </div>
                    <div className={classes.data}>
                        <div className={(description.isDirty && (description.isEmpty))
                            ? classes.incorrectData
                            : [classes.incorrectData, classes.hidden].join(' ')}>
                            Поле заполнено неверно
                        </div>
                        <label>Укажите описание</label>
                        <input type='tel' value={description.value}
                               onBlur={e => description.onBlur(e)}
                               onChange={e => description.onChange(e)}/>
                    </div>
                    <div className={classes.data}>
                        <div className={(price.isDirty && (price.isEmpty))
                            ? classes.incorrectData
                            : [classes.incorrectData, classes.hidden].join(' ')}>
                            Поле заполнено неверно
                        </div>
                        <label>Укажите цену</label>
                        <input type='number' value={price.value}
                               onBlur={e => price.onBlur(e)}
                               onChange={e => price.onChange(e)}/>
                    </div>
                    <div className={classes.button_block}>
                        <div className={classes.inner}>

                        </div>
                        <button disabled={!image.isInputValid || !category.isInputValid
                            || !title.isInputValid || !description.isInputValid || !price.isInputValid}
                                type='submit' onClick={e => addDishToMenu(e)}>Добавить
                        </button>
                    </div>
                </form>
            </Modal>
            <InfoModal modal={infoModal} setModal={setInfoModal}>
                <label>Блюдо успешно добавлено</label>
            </InfoModal>
        </div>
    );
};

export default AddDishModal;

image.value и все другие поля модалки изменяют свое состояние, но когда я делаю setDish и потом добавляю это блюдо в массив, в консоли я вижу, что блюдо представляет собой пустой объект ( {id: 0, image: '', count: 0, price: 0, totalPrice: 0, title: '', description: '', category: ''}), который, впринципе, так и сохраняется в массив. В чем может быть проблема?


Ответы (1 шт):

Автор решения: p1uton

Обновление стейта работает асинхронно, это значит, что после вызова setDish значение dish поменяется не сразу.

В этом месте использовать стейт вообще не нужно - достаточно объявить локальную переменную и передать ее в dispatch.

    const addDishToMenu = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
        e.preventDefault()

        const dish = {
            id: Date.now(),
            category: category.value,
            image: image.value,
            title: title.value,
            description: description.value,
            price: parseInt(price.value),
            count: 1,
            totalPrice: parseInt(price.value)
        }

        dispatch(addDishAction(dish))

        setModal(false)
        setInfoModal(true)
        setTimeout(() => {
            setInfoModal(false)
        }, 2000)
    }
→ Ссылка