首先我想说我有一个解决方案,但这似乎很荒谬,必须有更好的方法所以我将从我荒谬的解决方案开始。
我有一个显示我所在页面的表单。我希望用户能够输入页面并在输入时转到该页面。
我的组件看起来像:
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
所以这是有效的。。。如果我在《白鲸》第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函数中,从参考获取当前值
类似这样的东西:
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