Я только начал изучать redux< redux-toolkit и столкнулся с проблемой, что мой стат из редюсера "Время" всегда возвращает начальное значение, хотя в другом функциональном компоненте он работает корректно.
Редуктор
import { createSlice } from '@reduxjs/toolkit'
type TInitialState = {
value: number;
}
const initialState: TInitialState = {
value: 10,
}
const passTimerSlice = createSlice({
name: 'passTimer',
initialState,
reducers: {
setDefault: state => {
state.value = 12
},
addSeccond: state => {
state.value -= 1
}
},
})
export const { addSeccond, setDefault } = passTimerSlice.actions
export default passTimerSlice.reducer
useEffect(() => {
dispatch(slices.passTimer.setDefault())
passTimerId = setInterval(() => {
console.info('passTimer', passTimer)
if (passTimer <= 0) {
clearInterval(passTimerId)
return
}
dispatch(slices.passTimer.removeSeccond())
}, 1000)
return () => {
clearInterval(passTimerId) // Clear interval on component unmount
}
}, [passState])
буду рад любой подсказке
Перечитал документацию, но так и не нашел в чем моя ошибка.
Кроме того, ваше действие addSecond, но редуктор, кажется, вычитает секунду, не уверен, намеренно это или нет, но это кажется неправильным.
он должен сбросить таймер на значение по умолчанию, passState и Pastimer — это разные состояния, первое хранит, у кого сейчас ход, второе — количество секунд, которое у него есть для хода. Моя проблема в том, что когда я ставлю интервал, пастимер каждую секунду возвращает мне значение по умолчанию, хотя внутри работает корректно и время уменьшается
passState не является значимой зависимостью, поскольку на нее нет ссылки в обратном вызове useEffect. Что такое passTimer? Он закрыт в области обратного вызова, поэтому, скорее всего, никогда не будет другого значения. Я думаю, вам все равно следует отредактировать , включив в него полный минимальный воспроизводимый пример соответствующего кода, с которым вы работаете, чтобы читателям было понятно, что ваш код делает и когда/почему он это делает.





Каждый раз, когда ваш passState изменяется, вы отправляете действие slices.passTimer.setDefault(), поэтому я предполагаю, что вам либо нужен пустой массив зависимостей, либо удалить эту отправку.
в passState хранится тот, кто сейчас ходит, а диспетчеризация(slices.pastimer.setDefault()) нужна, чтобы после смены владельца хода таймер сбрасывался на значение по умолчанию
Весь passState, а не passState.value или что-то в этом роде? Просто ради интереса удалите его из массива зависимостей и посмотрите, что произойдет — если это исправит, этот passState постоянно меняется. Также взгляните на Redux DevTools, какие действия в каком порядке отправляются.
const passState = useAppSelector(state =>state.passState.value) вот так выглядит мое прошлое состояние «владельца хода», useAppSelector — это тот же useSelector из реакции-редукса, только с переопределенным типом. Если его удалить, ход не будет передан. Я проверил Redux WebKit, работает корректно. Я исправил эту проблему, добавив костыль из дополнительного прослушивателя изменения состояния timerState, надеюсь, мое понимание redux скоро улучшится и я смогу добавить более правильный ответ. Но если вас интересует моя ошибка, я могу открыть для вас репозиторий.
Я решил эту проблему, вынеся отслеживание изменения значения timerState в отдельный useEffect.
useEffect(() => {
console.info(timerState)
if (timerState <= 0) {
clearInterval(timerId)
console.info('time end')
}
}, [timerState])
Ваш
useEffectиспользует выбранное значениеpassStateв качестве зависимости, поэтому каждый раз, когда значениеpassStateобновляется, эффект запускается снова, каждый раз сбрасываяpassStateобратно на12. Мы можем только указать на очевидную проблему, но поскольку неясно, чего вы ожидаете от этого кода, то есть ожидаемого поведения, трудно сделать какие-либо предложения по исправлению/улучшению логики. Можете ли вы отредактировать, чтобы уточнить вариант использования и то, чего вы здесь пытаетесь достичь?