javascript - 在 Next.js 中访问查询值
问题描述
我正在开发 Next.js 应用程序并尝试创建无限滚动和搜索输入。
当用户到达页面底部时,无限滚动将再加载 6 个项目。搜索输入将过滤结果并仅返回标题中包含字符串输入的项目。
这两个功能单独工作都很好,问题在于将它们结合起来。
问题阶段是:
- 输入搜索输入 - 例如
"a"
- 滚动到页面底部
预期:"a"
打开搜索过滤器的更多结果。
实际: search
是一个空字符串,因此结果上没有过滤器。
在调试scrollHandler
函数时,search
prop 是一个空字符串,即使 URL 查询中存在搜索参数。
getServerSideProps
:
export async function getServerSideProps({ query }) {
const search = query.search || '';
const limit = query.limit || process.env.ITEMS
const params = {
limit,
skip: process.env.Items_INIT_SKIP,
orderBy: process.env.Items_INIT_ORDERBY,
search
};
const { data: items } = await getItems(params)
return { props: { items, search, limit } }
}
ItemsPage
零件:
const ItemsPage = ({ items, search, limit }) => {
const router = useRouter()
useEffect(() => {
window.addEventListener("scroll", handleScroll)
return () => {
window.removeEventListener("scroll", handleScroll)
}
}, [])
const handleScroll = () => {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
const newLimit = 6 + Number(limit);
const path = search ? `${router.pathname}?search=${search}` : router.pathname
const query = { ...router.query, limit: newLimit, search }
router.push({
pathname: router.pathname,
query
},
path)
}
}
const searchHandler = e => {
const search = e.target.value
router.push({
pathname: router.pathname,
query: {
search
},
})
}
return (
<div className={st(classes.root, {})}>
<Input className={classes.Search} value={search} label='search' type='text' onChange={searchHandler} />
<Items items={items} />
</div>
)
}
export default ItemsPage;
解决方案
将组件更改为class component
,并使用 HOC:withRouter
解决了问题,并允许访问查询参数和 props.
class ItemsPage extends React.Component {
scrollHandler = () => {
if (Math.ceil(window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
const { router, limit, search } = this.props
const newLimit = Number(limit) + Number(process.env.NEXT_PUBLIC_ITEMS_TO_ADD)
const path = search ? `${router.pathname}?search=${search}` : router.pathname
const query = { limit: newLimit, search }
router.push({
pathname: router.pathname,
query
},
path)
}
}
searchHandler = e => {
const { router } = this.props
const search = e.target.value
const path = search ? `${router.pathname}?search=${search}` : router.pathname
router.push({
pathname: router.pathname,
query: {
search
},
}, path)
}
componentDidMount() {
window.addEventListener("scroll", this.scrollHandler)
}
componentWillUnmount() {
window.removeEventListener("scroll", this.scrollHandler)
}
render() {
const { Items, router } = this.props
const { search } = router.query
return (
<div className={st(classes.root, {})}>
<Input className={classes.Search} value={search} label='search' type='text' onChange={this.searchHandler} />
<Items Items={Items} />
</div>
)
}
}
export default withRouter(ItemsPage)
推荐阅读
- wordpress - 如何通过 IP 地址限制对 WordPress 管理员登录页面的访问,而不影响客户注销过程?
- java - 如何在 Spring Security antmatchers 中使用参数
- sql - 在 PostgreSQL 中为特定 ID 选择最大值
- django - 使用来自不同模型模板的 kwargs 在 Django 中创建 CreateView
- java - 如果出现任何类型的异常,重定向到错误控制器?
- vue.js - VueJS 2:如何按顺序加载静态 JS?
- highcharts - 在 jhipster 中使用 highcharts
- spring - 硬件系统要求
- microsoft-graph-api - 是否可以让应用程序直接访问文件?
- android - android kotlin spinner 适用于 API 23,但不适用于 API 21