如何将React Router参数与状态同步



使用React Router Web。

假设我们有一条路由:/:user?showDetails=true。我们知道如何使用useParams钩子和类似useQuery自定义钩子的东西来从URL中获取数据。

此外,我们知道如何使用history.push(/baruchiro?showDetails=false)设置此数据。

但是,如果我们获取并设置这些数据,以防我们不使用这些数据将用户从一个页面重定向到另一个页面,而是更改当前组件(让用户保存其当前页面视图(,则意味着路由状态

如何使用路由作为一种状态,而不让组件因大量history.pushuseParams而变脏?

更新

我将这个自定义钩子发布为npm包:使用路由作为状态


如果您想将route用作state,您需要一种获取路由参数并更新它们的方法。

您无法避免使用CCD_ 9,因为这是您更改";状态";,您的route。但是您可以隐藏此命令以获得更干净的代码。

以下是如何在自定义挂钩中隐藏getupdate的示例,使它们看起来像常规的useState挂钩:

使用查询参数作为状态:

import { useHistory, useLocation} from 'react-router-dom'
const useQueryAsState = () => {
const { pathname, search } = useLocation()
const history = useHistory()
// helper method to create an object from URLSearchParams
const params = getQueryParamsAsObject(search)
const updateQuery = (updatedParams) => {
Object.assign(params, updatedParams)
// helper method to convert {key1:value,k:v} to '?key1=value&k=v'
history.replace(pathname + objectToQueryParams(params))
}
return [params, updateQuery]
}

使用路由参数作为状态:

import { generatePath, useHistory, useRouteMatch } from 'react-router-dom'
const useParamsAsState = () => {
const { path, params } = useRouteMatch()
const history = useHistory()
const updateParams = (updatedParams) => {
Object.assign(params, updatedParams)
history.push(generatePath(path, params))
}
return [params, updateParams]
}

请注意查询参数代码中的history.replace路由参数

用法:(不是我代码中的真正组件,如果有编译问题,很抱歉(

const ExampleComponent = () => {
const [{ user }, updateParams] = useParamsAsState()
const [{ showDetails }, updateQuery] = useQueryAsState()
return <div>
{user}<br/ >{showDetails === 'true' && 'Some details'}
<DropDown ... onSelect={(selected) => updateParams({ user: selected }) />
<Checkbox ... onChange={(isChecked) => updateQuery({ showDetails: isChecked} })} />
</div>
}

我使用react-router-dom-v6的URL搜索参数创建了以下NPM包来存储状态:https://www.npmjs.com/package/react-use-search-params-state

最新更新