Issue:inputVal
是我使用setState
更新的状态变量。
当按钮调用我的handleConfirmSubmit
函数时,它工作正常。
但是,如果我添加侦听按键然后触发函数onKeyUp
然后触发handleConfirmSubmit
的eventListener
......突然间,handleConfirmSubmit
看不到更新的状态值。
我在键入时添加了控制台注销inputVal
useEffect
,我可以确认它正在更新,但出于某种原因,取决于我调用handleConfirmSubmit
的位置,它可以看到或看不到更新的状态值。
代码:(一些不必要的东西已被去除)
export default function SingleInputModal(props){
const [cancelButton, setCancelButton] = useState(null);
const [inputVal, setInputVal] = useState(props.previousValue || '');
//ComponentDidMount
useEffect( () => {
//Listen for keypress
window.addEventListener('keyup', onKeyUp);
return () => {
window.removeEventListener('keyup', onKeyUp);
}
}, []);
useEffect( () => {
console.log('new inputval', inputVal);
},[inputVal])
const handleChange = (e) => {
console.log('handle Change ran', e.target.value);
setInputVal(e.target.value || '');
}
const handleConfirmSubmit = () => {
console.log('About to submit: ', inputVal);
props.handleConfirmation(false, inputVal)
}
const onKeyUp = (e) => {
if(props.submitOnEnter && e.key === 'Enter'){
//Submit
handleConfirmSubmit();
}
if(props.cancelOnESC && e.key === 'Escape'){
//Cancel
props.handleConfirmation(true, null);
}
}
return(
<div className="confirm"
>
<div className="modal singleInput"
>
<div className="content">
<input
className='myModal__textInput'
type='text'
value={inputVal}
onChange={handleChange}
/>
</div>
<div className="actions">
<a
onClick={handleConfirmSubmit}
>Submit</a>
</div>
</div>
</div>
)
}
您可以在 inputVal 更改时更新侦听器,否则侦听器将存储来自第一次渲染的 inputVal 值的副本。
useEffect( () => {
//Listen for keypress
window.addEventListener('keyup', onKeyUp);
return () => {
window.removeEventListener('keyup', onKeyUp);
}
}, [inputVal]);
您可以使用React.useCallback
来确保您拥有函数的新版本(因为例如handleConfirmSubmit
可以捕获其闭包中的inputVal
):
export default function SingleInputModal(props) {
const [cancelButton, setCancelButton] = useState(null);
const [inputVal, setInputVal] = useState(props.previousValue || "");
useEffect(() => {
window.addEventListener("keyup", onKeyUp);
return () => window.removeEventListener("keyup", onKeyUp);
}, []);
useEffect(() => console.log("new inputval", inputVal), [inputVal]);
const handleChange = e => {
console.log("handle Change ran", e.target.value);
setInputVal(e.target.value || "");
};
const handleConfirmSubmit = React.useCallback(
() => {
console.log("About to submit: ", inputVal);
props.handleConfirmation(false, inputVal);
},
[inputVal],
);
const onKeyUp = React.useCallback(
e => {
if (props.submitOnEnter && e.key === "Enter") {
// Submit
return handleConfirmSubmit();
}
if (props.cancelOnESC && e.key === "Escape") {
// Cancel
props.handleConfirmation(true, null);
}
},
[handleConfirmSubmit, props.submitOnEnter, props.cancelOnESC],
);
return (
<div className="confirm">
<div className="modal singleInput">
<div className="content">
<input className="myModal__textInput" type="text" value={inputVal} onChange={handleChange} />
</div>
<div className="actions">
<a onClick={handleConfirmSubmit}>Submit</a>
</div>
</div>
</div>
);
}