我构建的组件有问题。如果两者都输入,一个值 ( inclVal
) 必须大于另一个 ( )。exclVal
我想用 a 运行处理此问题的函数,setTimeout()
以便在道具停止更改后它不会更新一秒钟,以确保它不会更改用户在输入时输入的值。为此,我clearTimeout()
在一个else
block 中放入了 a ,以防止函数在 props 发生变化时执行,从而使其冗余。问题是clearTimeout()
由于某种原因它不起作用,并且只要if
输入块,更新功能就会运行,即使else
在超时间隔内输入块也是如此。
该组件是一个无状态的功能组件,使用 redux 进行状态管理。我已经阅读了很多关于如何使这些东西发挥作用的文章,但似乎没有任何帮助。任何帮助表示赞赏!
这是代码:
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import SelectPickerPulldown from '../../components/SelectPickerPulldown'
import TextInput from '../../components/TextInput'
import { odOptions } from '../../config/'
import { setODProperty } from '../../actions/odAnalyzerActions'
import { getConversion, getGreaterVal } from '../../utils/'
const InclusionExclusionOptions = ({ name,
analysisPoint,
paths,
exclVal,
exclUnit,
inclVal,
inclUnit,
getVal,
getUnit,
setSafeInclVal,
}) => {
const disabled = analysisPoint !== null || paths ? false : true
let inclEntryTimer = null
const exclCompare = getConversion(exclUnit)(exclVal)
const inclCompare = getConversion(inclUnit)(inclVal)
if (exclVal > 0 && inclVal > 0 && exclCompare > inclCompare) {
const safeInclVal = getGreaterVal(exclVal, exclUnit, inclUnit)
console.log('entering timeout');
inclEntryTimer = setTimeout( () => {
console.log('dispatching timeout action');
setSafeInclVal(safeInclVal)
}, 1000)
}
else {
console.log('clearing timeout');
clearTimeout(inclEntryTimer)
inclEntryTimer = null
}
return (
<div className="form-group" >
<h4>Inclusion/Exclusion Options</h4>
<ul className={name}>
<li className={`text-select-group ${disabled ? name + ' disabled' : name}`}>
<p>Exclusion Radius</p>
<div className="radius-setting">
<TextInput
type="number"
name="exclVal"
value={exclVal}
onChange={getVal}
/>
<SelectPickerPulldown
value={'exclUnit'}
options={odOptions.units}
selected={exclUnit}
getSelected={getUnit}
/>
</div>
</li>
<li className={`text-select-group ${disabled ? name + ' disabled' : name}`}>
<p>Inclusion Radius</p>
<div className="radius-setting">
<TextInput
type="number"
name="inclVal"
value={inclVal}
onChange={getVal}
/>
<SelectPickerPulldown
value={'inclUnit'}
options={odOptions.units}
selected={inclUnit}
getSelected={getUnit}
/>
</div>
</li>
</ul>
</div>
)
}
InclusionExclusionOptions.propTypes = {
name: PropTypes.string,
exclVal: PropTypes.number,
exclUnit: PropTypes.string,
inclVal: PropTypes.number,
inclUnit: PropTypes.string,
getVal: PropTypes.func,
getUnit: PropTypes.func,
}
const mapStateToProps = (state, ownProps) => {
const name = 'inclusion-exclusion-options'
const { analysisPoint,
paths,
exclVal,
exclUnit,
inclVal,
inclUnit } = state.odAnalyzerState
return {
name,
analysisPoint,
paths,
exclVal,
exclUnit,
inclVal,
inclUnit,
}
}
const mapDispatchToProps = dispatch => {
return {
getUnit: option => dispatch(setODProperty(option)),
getVal: (e, name) => dispatch(setODProperty({[name]: parseInt(e.target.value)})),
setSafeInclVal: safeInclVal => dispatch(setODProperty({inclVal: safeInclVal}))
}
}
export default connect(
mapStateToProps,
mapDispatchToProps)(InclusionExclusionOptions)
这是使用类组件的更新代码componentDidUpdate()
:
class InclusionExclusionOptions extends React.Component{
constructor(props){
super(props)
this.inclEntryTimer = null
}
componentDidUpdate(props){
const { exclVal,
exclUnit,
inclVal,
inclUnit,
} = this.props
const exclCompare = getConversion(exclUnit)(exclVal)
const inclCompare = getConversion(inclUnit)(inclVal)
if (!!exclVal && !!inclVal && exclCompare > inclCompare) {
const safeInclVal = getGreaterVal(exclVal, exclUnit, inclUnit)
console.log('entering timeout')
this.inclEntryTimer = setTimeout( () => {
console.log('dispatching timeout action');
this.props.setSafeInclVal(safeInclVal)
}, 3000)
}
else {
console.log('clearing timeout');
clearTimeout(this.inclEntryTimer)
this.inclEntryTimer = null
}
}
render() {
const { name,
analysisPoint,
paths,
exclVal,
exclUnit,
inclVal,
inclUnit,
getVal,
getUnit,
} = this.props
const disabled = analysisPoint !== null || paths ? false : true
return (
<div className="form-group" >
<h4>Inclusion/Exclusion Options</h4>
<ul className={name}>
<li className={`text-select-group ${disabled ? name + ' disabled' : name}`}>
<p>Exclusion Radius</p>
<div className="radius-setting">
<TextInput
type="number"
name="exclVal"
value={exclVal}
onChange={getVal}
/>
<SelectPickerPulldown
value={'exclUnit'}
options={odOptions.units}
selected={exclUnit}
getSelected={getUnit}
/>
</div>
</li>
<li className={`text-select-group ${disabled ? name + ' disabled' : name}`}>
<p>Inclusion Radius</p>
<div className="radius-setting">
<TextInput
type="number"
name="inclVal"
value={inclVal}
onChange={getVal}
/>
<SelectPickerPulldown
value={'inclUnit'}
options={odOptions.units}
selected={inclUnit}
getSelected={getUnit}
/>
</div>
</li>
</ul>
</div>
)
}
}
根据 Brandon 的建议,我可以通过在重新声明它之前简单地清除它来清除超时。我打破了一个明确的超时功能
clearInclEntryTimer(){
clearTimeout(this.inclEntryTimer)
this.inclEntryTimer = null
}
然后在块的顶部和if
块中调用它else
。效果很好。谢谢您的帮助!