检测反应路由器中的先前路径?
Posted
技术标签:
【中文标题】检测反应路由器中的先前路径?【英文标题】:Detect previous path in react router? 【发布时间】:2017-01-10 08:44:34 【问题描述】:我正在使用反应路由器。我想检测我来自的上一页(在同一个应用程序中)。我在我的上下文中有路由器。但是,我在路由器对象上看不到任何属性,例如“先前路径”或历史记录。我该怎么做?
【问题讨论】:
检查this.props.history.location.pathname
。它应该可以工作。
你好,你有什么想法,如何从应用程序或网络应用程序中获取上一页?用户从哪里访问网络应用程序?可以在 reactjs 上检查吗?
【参考方案1】:
您可以在 componentWillReceiveProps
生命周期方法中保存以前的路径。逻辑非常接近troubleshooting section 的react-router
文档中提供的示例。
<Route component=App>
/* ... other routes */
</Route>
const App = React.createClass(
getInitialState()
return prevPath: ''
,
componentWillReceiveProps(nextProps)
if (nextProps.location !== this.props.location)
this.setState( prevPath: this.props.location )
)
最近,从状态访问它。
【讨论】:
谢谢。我将带有路径的状态与路径名一起推送。你的解决方案更好。 很高兴为您提供帮助! 它对我不起作用。我使用 在我的应用程序中导航,当我单击组件中的任何链接时,componentWillReceiveProps 不会运行。 我使用 componentWillUnmount 设置状态,但如果我移动到其他组件,除非我将其传递给组件,否则我无法访问状态。 @AlexandrLazarev 功能组件呢?你介意更新你的答案吗?提前致谢。【参考方案2】:如果你使用react-router-redux
,你可以创建一个reducer来挂钩react-router-redux调度的事件。
export default function routerLocations(state = [], action)
switch (action.type)
case "@@router/LOCATION_CHANGE":
return [...state, action.payload]
default:
return state;
【讨论】:
除此之外,您可以导入动作名称import LOCATION_CHANGE from 'react-router-redux';
如果你使用connected-react-router
你可以使用import LOCATION_CHANGE from 'connected-react-router';
@Stuck 它只是在控制台上打印@@router/LOCATION_CHANGE
【参考方案3】:
您可以使用<Link>
组件传递状态,在本例中为路径名:
<Link to=pathname: '/nextpath', state: prevPath: location.pathname >Example Link</Link>
然后您可以在下一个组件中从this.props.location.state
访问prevPath
【讨论】:
你也可以用browserHistory.push()
做同样的事情
巧妙的把戏。但是,如果您不小心,就会有一个明显的问题。页面A
将用户发送到页面B
,状态为pathname: pathB, state: prevPath: pathA
。当在页面B
并且用户导航到上一个页面,传递类似结构的状态时,您可以看到问题。
这会重定向到运行在 3000 端口的 API 主机,react app 在 3001 上。如何解决?
使用state
对我来说是有问题的,因为它在刷新后仍然存在。填写表格后,我在“谢谢”页面上使用它。如果他们不是来自原始表单,我不希望人们访问此页面。还是我做错了?
是的,状态是一个非常糟糕的答案【参考方案4】:
如果您使用的是<Redirect />
组件,您可以添加一个from
属性,该属性将添加到您重定向到的组件中的location.state
。
// in the redirecting component
<Redirect
to=
pathname: '/login',
state: from: location
/>
//in the other component you redirected to
...
const location = props.location.state;
...
【讨论】:
您能否请添加有关“其他组件”的更多详细信息?以及如何传递和访问道具?谢谢【参考方案5】:使用 react-router 的 useHistory 钩子可以在功能组件的无状态中转到上一个路径。更多信息请点击链接https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/hooks.md#useroutematch
import useHistory from "react-router-dom";
function demo ()
let history = useHistory();
const goToPreviousPath = () =>
history.goBack()
return (
<div>
<Button
onClick=goToPreviousPath
>
Back
</Button>
</div>
):
【讨论】:
您应该注意,如果您重新加载页面,那么新的先前路径将成为您刚刚重新加载的路径。如果你重新加载2次然后尝试history.goBack()
,你会遇到两次相同的页面,这不是你通常想要的。
现在是 2021 年,情况并非如此。我相信他们已经更新了它并且他们已经修复了这个错误 @Dev。我在我的代码中使用了上面的代码,并多次尝试重新加载页面,但效果很好。
这种方法的问题是它保留了 > 浏览器按钮并且 > 变为启用状态。如果您想始终在最新页面上(> 禁用),而只是将上一个屏幕显示为您的最新页面,这是行不通的。
这提供了一种向后导航的方法。但它没有提供访问问题所在的前一个 URL 的方法【参考方案6】:
如果有帮助,如果您不希望组件重新渲染并仍然获得以前的路径,请参阅此解决方案..
import useLocation from 'react-router-dom';
export default () =>
const location = useLocation();
const path = location.pathname;
const store = window.localStorage;
let url = '';
let prevUrl = '';
url = store.getItem('url');
store.setItem('prevUrl', url);
store.setItem('url', path);
url = store.getItem('url');
prevUrl = store.getItem('prevUrl');
return url, prevUrl ;
【讨论】:
只需将其导入您想要的位置并执行const url, prevUrl = importedFunc();
在 s-s-r 中小心:窗口对象未定义。【参考方案7】:
React - 使用 props 获取上一个路径
console.log(props.history.location.state && props.history.location.state.from.pathname);
如果你使用<Link> OR <Redirect> ? pathname : undefined
重定向
【讨论】:
【参考方案8】:不要检查上一页是什么,而是从不同的角度解决问题。将当前页面作为道具传递给您要导航到的组件或链接。
在我调用 history.push 或单击链接的上一个页面或组件中,我添加了当前页面的状态,例如,
history.push(`/device/detail`, from: 'device detail page' );
然后我可以使用 history.location.state.from 访问上一页的内容
【讨论】:
谢谢!出于某种原因,我不知道在哪里可以找到from
,但多亏了你,我找到了它。 const history = useHistory(); console.log(history.location.state.from);
只是history.location.from
而不是history.location.state.from
@Quirzo
应该是 history.location.state.from 因为 history.location 没有 from 属性。所以 history.location.from 不应该存在。你可以确认这个@defraggled
您能否粘贴更详细的答案,以便人们从您的出色答案中受益?现在它没有处于有用的状态,因为没有例子说明事情是如何联系在一起的......任何愿意改进这个答案的人???
您的回答值得 100 票赞成,谢谢:D【参考方案9】:
使用context
可以存储之前的location
路径名:
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 //--> previous 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>
或者
history.push(route.from);
注意:RouterContext
应该在Router
组件下,如果您不想更新状态,可以改用useRef
。如果您需要更多持久性,请使用localStorage
【讨论】:
【参考方案10】:此答案使用与@AlexandrLazarev 类似的方法,但通过 React Hooks 实现。这可确保捕获对路径的所有更改,无论它们是如何启动的。先前的路径值存储在***组件的状态中,然后可以作为道具传递给子组件,或者如果您使用像 Redux 这样的全局状态提供程序,可以将其添加到存储中:
import useEffect, useState from 'react'
cont App = ( location ) =>
const [currentPath, setCurrentPath] = useState(null);
const [previousPath, setPreviousPath] = useState(null);
useEffect(() =>
if (location.pathname !== currentPath)
setPreviousPath(currentPath);
setCurrentPath(location.pathname);
, [location.pathname]);
标记中的实现类似于下面的 sn-p。我一直在使用 Reach Router,但考虑到它的 been merged 和 React Router 应该也可以在那里工作。 Router
component 使 location
属性可供其所有子级使用,并在其 pathname
属性下保存当前路径的值
<Router>
<App path="/*" />
<Router/>
【讨论】:
【参考方案11】:我需要一种方法来有条件地导航,仅当先前的路径等于特定路径时。有了一个功能组件,它的工作原理是这样的。仅当路由为 '/cart'
时,&&
才会触发 .push()
方法。
import useHistory from "react-router-dom";
const history = useHistory();
history.location.pathname === '/cart' && history.push('/checkout');
【讨论】:
"仅当先前路径等于特定路径时才导航" 但是这个 -history.location.pathname
是当前路径。以上是关于检测反应路由器中的先前路径?的主要内容,如果未能解决你的问题,请参考以下文章