【发布时间】:2021-05-28 20:09:50
【问题描述】:
我正在尝试构建一个验证码页面。
如果我为每个输入框创建一个单独的状态,然后使用下面的代码,它就可以正常工作。
<input type="number" value={inputOne} className={styles.codeInput} onChange={e => setInputOne(e.target.value}/>
但是,我试图将所有四个输入框的状态合并到一个状态对象中。
现在,当我输入一个数字时,它会移动到下一个输入,但它永远不会呈现该值。在开发工具中,我看到值会像更新一样闪烁,但它仍然保持为“value”而不是“value="1"”。
但是,如果我对我的代码做任何其他事情,例如更改 p 标签的文本,然后它会突然更新并且输入显示正确的值。
我只是想弄清楚我在这里做错了什么。
这是我当前的代码。
import { useState } from 'react'
import styles from '../../styles/SASS/login.module.scss'
export default function Verify(params) {
const [verifCode, setVerifCode] = useState(['','','','']);
const inputHandler = (e, index) => {
// get event target value
let value = e.target.value;
// update state
let newState = verifCode;
newState[index] = value;
setVerifCode(newState);
// move focus to next input
if (e.target.nextSibling) {
e.target.nextSibling.focus()
} else {
// if at the last input, remove focus
e.target.blur();
}
}
return (
<div className={styles.verify}>
<p className={styles.title}>Verification</p>
<p className={styles.message}>Please enter the verification code we sent to your email / mobile phone.</p>
<div className={styles.form}>
<input type="number" value={verifCode[0]} className={styles.codeInput} onChange={e => inputHandler(e, 0)}/>
<input type="number" value={verifCode[1]} className={styles.codeInput} onChange={e => inputHandler(e, 1)}/>
<input type="number" value={verifCode[2]} className={styles.codeInput} onChange={e => inputHandler(e, 2)}/>
<input type="number" value={verifCode[3]} className={styles.codeInput} onChange={e => inputHandler(e, 3)}/>
</div>
<div className={styles.footer}>
<button>Verify Code</button>
</div>
</div>
)
};
【问题讨论】:
-
React 进行浅层比较以确定状态是否已更改,您的
setVerifCode始终指向相同的引用,因此它们是相等的。 -
啊。明白了。如果我在页面上编辑任何其他内容,知道为什么它似乎有效吗?试图了解理论上发生了什么。
-
如果组件中的其他一些 not 浅相等的状态发生变化,它将触发更新,该更新将使用您在
verifCode中更改的状态进行渲染,甚至虽然 react 仍然不知道verifCode已经改变了。关键是 react 需要能够知道何时需要更新,这就是为什么您必须始终不可变地更新状态。
标签: javascript reactjs state use-state