React useEffect:对值更改做出反应以更新另一个也是依赖项的值
React useEffect: react on a value change to update another one who's also a dependency
我有一个大分页视图 table。
我想在 URL 查询参数中包含页面索引,以便能够通过共享 URL.
来共享 table 的特定页面
我的问题是页面不是唯一的查询参数,所以我需要做的是,当页面更改时:
- 检索当前查询参数
- 从旧的和新的页面创建新的查询参数
- 更新查询参数。
但是,更新查询参数是个问题,因为查询参数是检索旧参数的函数的依赖项,我陷入了这个循环。
我第一次尝试做这样的事情:
import query from 'qs'
import { useLocation, useHistory } from 'react-router-dom'
function Comp() {
const [pageIndex, setPageIndex] = useState(0)
// Updates the query params using the provided ones.
const updateQueryParams = useCallback(
(pageIndex) => {
const oldSearch = query.parse(location.search, { ignoreQueryPrefix: true })
const newSearch = { ...oldSearch, pageIndex }
history.push({ pathname: location.pathname, search: query.stringify(newSearch) })
},
[location.search, location.pathname]
)
// Updates the query params when pageIndex changes.
useEffect(() => updateQueryParams(pageIndex), [updateQueryParams, pageIndex])
}
但是更新查询参数会更新 location.search
,这是 updateQueryParams
回调的依赖项,它会触发无限循环。
我尝试使用 useRef
来存储搜索和路径名,手动更新它们,但我一直无法找到可行的解决方案。
我最后一次尝试是在自定义挂钩中提取逻辑以将问题分解成更小的部分(我将不得不在其他地方重用这段逻辑)。
这个钩子的当前状态是:
import { useLocation, useHistory } from 'react-router-dom'
import { useRef, useCallback } from 'react'
import query from 'qs'
export default function useQueryParams<QueryParams extends query.ParsedQs>(): [
QueryParams,
(newSearch: QueryParams) => void
] {
const location = useLocation()
const history = useHistory()
const search = useRef(query.parse(location.search, { ignoreQueryPrefix: true }) as QueryParams)
const pathname = useRef(location.pathname)
const setSearch = useCallback(
(newSearch: QueryParams) => {
history.push({ pathname: pathname.current, search: query.stringify(newSearch) })
search.current = newSearch
},
[history, pathname]
)
return [search.current, setSearch]
}
但这并没有解决我的问题。
尝试访问路由会触发无限循环,我在控制台中收到 Warning: Maximum update depth exceeded
错误。
问题是由我的路由声明方式引起的。
解决方案是根据此模式更新我的所有路线:
<Route path="/login" component={Login} />
给这个:
<Route path="/login">
<Login />
</Route>
我有一个大分页视图 table。 我想在 URL 查询参数中包含页面索引,以便能够通过共享 URL.
来共享 table 的特定页面我的问题是页面不是唯一的查询参数,所以我需要做的是,当页面更改时:
- 检索当前查询参数
- 从旧的和新的页面创建新的查询参数
- 更新查询参数。
但是,更新查询参数是个问题,因为查询参数是检索旧参数的函数的依赖项,我陷入了这个循环。
我第一次尝试做这样的事情:
import query from 'qs'
import { useLocation, useHistory } from 'react-router-dom'
function Comp() {
const [pageIndex, setPageIndex] = useState(0)
// Updates the query params using the provided ones.
const updateQueryParams = useCallback(
(pageIndex) => {
const oldSearch = query.parse(location.search, { ignoreQueryPrefix: true })
const newSearch = { ...oldSearch, pageIndex }
history.push({ pathname: location.pathname, search: query.stringify(newSearch) })
},
[location.search, location.pathname]
)
// Updates the query params when pageIndex changes.
useEffect(() => updateQueryParams(pageIndex), [updateQueryParams, pageIndex])
}
但是更新查询参数会更新 location.search
,这是 updateQueryParams
回调的依赖项,它会触发无限循环。
我尝试使用 useRef
来存储搜索和路径名,手动更新它们,但我一直无法找到可行的解决方案。
我最后一次尝试是在自定义挂钩中提取逻辑以将问题分解成更小的部分(我将不得不在其他地方重用这段逻辑)。
这个钩子的当前状态是:
import { useLocation, useHistory } from 'react-router-dom'
import { useRef, useCallback } from 'react'
import query from 'qs'
export default function useQueryParams<QueryParams extends query.ParsedQs>(): [
QueryParams,
(newSearch: QueryParams) => void
] {
const location = useLocation()
const history = useHistory()
const search = useRef(query.parse(location.search, { ignoreQueryPrefix: true }) as QueryParams)
const pathname = useRef(location.pathname)
const setSearch = useCallback(
(newSearch: QueryParams) => {
history.push({ pathname: pathname.current, search: query.stringify(newSearch) })
search.current = newSearch
},
[history, pathname]
)
return [search.current, setSearch]
}
但这并没有解决我的问题。
尝试访问路由会触发无限循环,我在控制台中收到 Warning: Maximum update depth exceeded
错误。
问题是由我的路由声明方式引起的。
解决方案是根据此模式更新我的所有路线:
<Route path="/login" component={Login} />
给这个:
<Route path="/login">
<Login />
</Route>