在 goBack() 反应路由器 v4 之前检查历史以前的位置

Posted

技术标签:

【中文标题】在 goBack() 反应路由器 v4 之前检查历史以前的位置【英文标题】:Check history previous location before goBack() react router v4 【发布时间】:2018-05-04 17:01:36 【问题描述】:

我的目标是启用“返回”按钮,但前提是用户返回的路线/路径属于某个类别。

更准确地说,我有两种路线:/<someContent>/graph/<graphId>。当用户在图表之间导航时,他们应该能够返回上一个图表,但不能返回/... 路线。这就是为什么我不能简单地运行history.goBack(),我需要先检查位置。

const history = createHashHistory();
const router = (
        <ConnectedRouter history=history>
            <Switch>
                <Route exact path='/' component=Home></Route>
                <Route exact path='/extension' component=Home></Route>
                <Route exact path='/settings' component=Home></Route>
                <Route exact path='/about' component=Home></Route>
                <Route exact path='/search' component=Home></Route>
                <Route exact path='/contact' component=Home></Route>
                <Route path='/graph/:entityId' component=Graph></Route>
            </Switch>
        </ConnectedRouter>
);

我想在Graph 组件中实现类似的东西:

if (this.props.history.previousLocation().indexOf('graph') > -1)
    this.props.history.goBack();
 else 
    this.disableReturnButton();

这个问题也适用于goForward(),因为如果不适用,我想禁用“前进”按钮。用户也可以使用this.props.history.push(newLocation)移动

显然,当用户四处走动时,我想避免使用诸如登录localStorage 或redux store 之类的副作用,这感觉不太自然,我知道该怎么做。

【问题讨论】:

如果您的历史记录是由window.history 支持的,您就看不到.back().forward() 背后的内容????我不确定哈希历史是否以相同的方式实现,但我很确定它具有相同的 API,所以没有运气。我认为在内存中保留历史的影子副本(您的 redux store 想法)是最实用的方式。 【参考方案1】:

在浏览Link 组件或history.push 时,您可以将当前位置传递给另一个Route 组件

喜欢

<Link to=pathname: '/graph/1', state:  from: this.props.location.pathname  />

history.push(
  pathname: '/graph/1',
  state:  
      from: this.props.location.pathname
  
)

然后你可以像this.props.location.state &amp;&amp; this.props.location.state.from一样在你的组件中获取这个位置,然后决定你是否想要goBack

【讨论】:

状态是否以某种方式持续存在?我的意思是,如果用户来回或多次倒退,这种状态会按预期工作吗? 不,它不会持续存在,您必须确保每次使用后退或前进时都传递它 我不妨将位置作为列表存储在本地存储或 redux 存储中,但谢谢:) 当然这是一种方法,因为你不想要它,我添加了一个仅限路由器的解决方案 更新:是的,您可以使用useLocation【参考方案2】:

使用context可以存储之前的位置pathname

const RouterContext = React.createContext();

const RouterProvider = (children) => 
  const location = useLocation()
  const [route, setRoute] = useState( //--> it can be replaced with useRef or localStorage
    to: location.pathname,
    from: location.pathname
  );

  useEffect(()=> 
    setRoute((prev)=> (to: location.pathname, from: prev.to) )
  , [location]);
  
  return <RouterContext.Provider value=route>
    children
  </RouterContext.Provider>

那么,在RouterProvider下的某个组件中:

const route = useContext(RouterContext);

 //...
 <Link to=route.from>
     Go Back
 </Link>

【讨论】:

以上是关于在 goBack() 反应路由器 v4 之前检查历史以前的位置的主要内容,如果未能解决你的问题,请参考以下文章

反应路由器 v4 重定向不起作用

反应路由器 v4 onUpdate

javascript 反应页面转换(假设反应路由器v4)

突出显示反应路由器 v4 中的默认链接

用开玩笑酶测试反应路由器 v4

反应路由器 v4 默认页面(未找到页面)