При изменении состояния в 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 шт):
Обновление стейта работает асинхронно, это значит, что после вызова 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)
}