在 goBack() react-router v4 之前检查历史以前的位置

IT技术 javascript reactjs ecmascript-6 react-router
2021-03-28 00:44:33

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

更准确地说,我有两种 Routes :/<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,这感觉不太自然,而且我知道该怎么做。

2个回答

在浏览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 && this.props.location.state.from,然后再决定是否wan't到goBack与否

状态是否以某种方式持续存在?我的意思是如果用户来回或向后几次,这种状态会按预期工作吗?
2021-05-27 00:44:33
不,它不会持续存在,您必须确保每次使用前后都通过它
2021-06-01 00:44:33
当然这是一种方法,因为你不想要它,我添加了一个仅路由器的解决方案
2021-06-07 00:44:33
更新:是的,您可以使用useLocation
2021-06-10 00:44:33
我不妨将位置存储为本地存储或 redux 存储中的列表,但谢谢:)
2021-06-18 00:44:33

使用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>