javascript - 对我的表单的 value 属性的 React 引用没有更新
问题描述
首先我想说我有一个解决方案,但这似乎很荒谬,必须有更好的方法。所以我将从我荒谬的解决方案开始。
我有一个表格,显示我在哪个页面上。我希望用户能够进入一个页面并在进入时转到该页面。
我的组件看起来像:
const BookPagination = (props) => {
const history = useHistory()
const { items, bookTitle, currentPageId } = props
const [currentPage, setCurrentPage] = useState(currentPageId)
const totalPages = items.length
const ENTER = 13
// items is just a bunch of arrays with info about each page (each of which have an id)
const handlePageInput = (e) => {
if (e.keyCode === ENTER) {
e.preventDefault()
history.push({
pathname: `/books/${bookTitle}/id/${items[currentPage - 1].id}` //page id's start @ 1
})
} else {
setCurrentPage(e.target.value)
}
}
return (
<div className={'.pageSelector'}>
<span>
<input type="number"
min="1"
max={totalPages}
value={currentPage}
onKeyDown={handlePageInput}
onChange={handlePageInput}
/>
of {totalPages}
</span>
</div>
)
}
export default BookPagination
所以这行得通...如果我在 Moby Dick 第 20 页上有一个书签,我可以转到,/books/mobydick/id/20
表单将从20
输入框中开始,它会在我想要的任何地方导航(我已经排除了边界检查的代码) .
我的问题:
每次我对输入进行更改时,这个东西都会渲染..如果我删除 20 并输入 19 并按回车键.. 那是 6 个渲染
Initial
, 20->2
, 2->0
, 0->1
, 1->19
,render new page
这是因为我的状态每次都在更新..
这是我可以弄清楚如何在页面加载时从当前页码开始并对其进行编辑的唯一方法......如果我从一个开始,其他尝试不会让我更新值..
我该如何解决?
我想我正在寻找的是 React.createRef() 但我尝试了以下方法:
添加 value={currentPageId}
到ref={inputElement}
表单
添加 const inputElement = React.createRef()
到组件的顶部
删除状态变量 currentPage
编辑 handlePageInput
到以下内容:
const handlePageInput = (e) => {
if (e.keyCode === ENTER) {
e.preventDefault()
history.push({
pathname: `/books/${bookTitle}/id/${items[inputElement.current.value - 1].id}`
})
} else {
inputElement.current.value = e.target.value
}
}
但它不会让我删除输入框的值......在输入框中上下单击也不会做任何事情。如果我在第 200 页输入,则无法将其更改为任何其他页面。
使用这种方法,
如果我删除value={currentPageId}
并留下没有值属性的表单,
- 更新我
history.push pathname
的.../id/${items[inputElement.current.valueAsNumber - 1].id}
我可以输入我想要的任何页面,并正确导航...我的问题是,当我进入一个页面时,输入框中没有任何内容可以开始...这就是我useState()
首先要更新它的方式...
我错过了什么?
解决方案
从您的输入中删除 onChange 并保留 onKeyDown。在您的 handlePageInput 函数中,从 ref 获取当前值。
像这样的东西:
const BookPagination = (props) => {
const history = useHistory()
const { items, bookTitle, currentPageId } = props
const totalPages = items.length
const ENTER = 13
const inputElement = useRef(null);
// items is just a bunch of arrays with info about each page (each of which have an id)
const handlePageInput = (e) => {
if (e.keyCode === ENTER) {
e.preventDefault()
const currentValue = inputElement.current.value;
history.push({
pathname: `/books/${bookTitle}/id/${items[currentValue - 1].id}` //page id's start @ 1
})
}
}
return (
<div className={'.pageSelector'}>
<span>
<input type="number"
ref={inputElement}
min="1"
max={totalPages}
defaltValue={currentPageId}
onKeyDown={handlePageInput}
/>
of {totalPages}
</span>
</div>
)
}
export default BookPagination