У ReactJS Возникли проблемы с установкой состояния при использовании эффекта при изменении зависимостей

#reactjs #react-hooks #use-effect

#reactjs #реагирующие крючки #использование-эффект

Вопрос:

Я пытаюсь установить состояние для dischargeMeasureInput.Point2D.speed, когда пользователи вводят как время, так и раунд. Он работает нормально, если не «удерживает» клавишу при изменении значения time или round, но когда я УДЕРЖИВАЮ пробел или любые другие клавиши на <Input {time,round} />, это вызывает бесконечный цикл. Кто-нибудь знает, как это исправить?

 const [dischargeMeasureInput, setDischargeMeasureInput] = useState({
        discOperatId: null, discMeasureId: null,
        orderNo: '1', depthPoint: '3', depth: null, distant: null,
        point2D: { surfaceD: null, time: null, round: null, speed: null }
})    

useEffect(() => {
        if (dischargeMeasureInput.point2D.time amp;amp; dischargeMeasureInput.point2D.round) {
               axios()...
                .then(res => {
                    if (res.data) {
                        setDischargeMeasureInput({ ...dischargeMeasureInput, point2D: { ...dischargeMeasureInput.point2D, speed: res.data.velocityPoint1 } })
                    }
                    else {
                        setDischargeMeasureInput({ ...dischargeMeasureInput, point2D: { ...dischargeMeasureInput.point2D, speed: null } })
                    }
                })
                .catch(err => {
                    console.log(err)
                })
        }

}, [dischargeMeasureInput.point2D.time, dischargeMeasureInput.point2D.round])

//child Component
<Input value={props.dischargeMeasureInput.point2D.time}
       onChange={(e) => props.setDischargeMeasureInput({ ...props.dischargeMeasureInput, point2D: { ...props.dischargeMeasureInput.point2D, time: e.target.value } })}/>
                
<Input value={props.dischargeMeasureInput.point2D.round}
       onChange={(e) => props.setDischargeMeasureInput({ ...props.dischargeMeasureInput, point2D: { ...props.dischargeMeasureInput.point2D, round: e.target.value } })} />
                
<Input value={props.dischargeMeasureInput.point2D.speed}
       onChange={(e) => props.setDischargeMeasureInput({ ...props.dischargeMeasureInput, point2D: { ...props.dischargeMeasureInput.point2D, speed: e.target.value } })} />
 

Вот короткий .gif

Ответ №1:

Хорошо, я понял это, кажется, есть условие гонки. Мне просто нужно добавить флаг bool перед setState. Эта ссылка мне помогает https://medium.com/hackernoon/avoiding-race-conditions-when-fetching-data-with-react-hooks-220d6fd0f663

 useEffect(() => {
    let canceled = false
    
    if(!canceled)
     setDischargeMeasureInput({ ...dischargeMeasureInput, point2D: { ...dischargeMeasureInput.point2D, speed: res.data.velocityPoint1 } })
    }
    
    //and cleanup function
    return () => (canceled = true)
})