在将 react-router 5 与 redux 7 一起使用时,react-router <Link> 在转到新路由后不会重置状态
Posted
技术标签:
【中文标题】在将 react-router 5 与 redux 7 一起使用时,react-router <Link> 在转到新路由后不会重置状态【英文标题】:While using react-router 5 with redux 7 react-router <Link> is not resetting state after going to new route 【发布时间】:2021-12-01 14:10:22 【问题描述】:我正在使用以下版本:
`"react-router": "^5.2.0",`
`"react-router-domreact-router": "^5.2.0",`
不确定我当前的设置是否对 React-router 5 友好,在此之前我使用的是 v5 之前的版本。
此示例中的问题在于<Route component=withTracker(InterviewContainer) path="/interviews/companies/:companyId" />
和<Link/>
这是我的场景:
-
主页加载了公司链接列表
点击公司
<Link />
,它将我路由到/interviews/companies/:companyId
页面加载正常,我看到了该特定公司的图片等
点击浏览器的返回按钮
点击另一个公司 <Link />
指向不同的 companyId
问题:对于#5,当公司页面最初加载时,由于某种原因,它加载了陈旧的图像和数据。所以换句话说,我从第 2 步开始短暂地看到前一家公司的数据和图像,直到我的 React 钩子发出新的调用来获取这个新 CompanyId 的数据并用正确的数据重新绘制浏览器(companyId 的数据表示在新路线)
index.tsx(注意此处使用BrowserRouter)
import BrowserRouter as Router from 'react-router-dom';
//...more code and then:
render(
<>
<div className="Site">
<Provider store=store>
<Router>
<App />
</Router>
</Provider>
</div>
<Footer />
</>,
);
App.ts
import Route, RouteComponentProps, Switch from 'react-router-dom';
...more code and then here are my routes:
<Switch>
<Route component=withTracker(HomePageContainer) exact path="/" />
<Route
path="/companies/:companyId/details"
render=(props: RouteComponentProps< companyId: string >) => (
<CompanyDetailContainer ...props fetchCompanyNew=fetchCompanyNew httpRequest=Request useFetchCompany=useFetchCompany />
)
/>
<Route component=withTracker(InterviewContainer) path="/interviews/companies/:companyId" />
<Route component=withTracker(About) path="/about" />
<Route component=withTracker(Container) path="/" />
<Route component=withTracker(NotFound) path="*" />
</Switch>
公司链接的编码方式如下:
注意:我使用的是 Redux 状态 "react-redux": "^7.2.1", "redux": "^4.0.5", "redux-thunk": "^2.3.0",
InterviewContainer.tsx(进行公司获取的父级)
class InterviewContainer extends Component<PropsFromRedux & RouteComponentProps< companyId: string >>
componentDidMount()
const fetchCompany = this.props;
const companyId = this.props.match.params;
fetchCompany(companyId);
render()
const company = this.props;
return (company && <Interview className="ft-interview" company=company />) || null;
const mapState = (state: RootState) => (
company: state.company.company,
);
const mapDispatch =
fetchCompany: fetchCompanyFromJSON,
;
const connector = connect(mapState, mapDispatch);
type PropsFromRedux = ConnectedProps<typeof connector>;
export default withRouter(connect(mapState, mapDispatch)(InterviewContainer));
LinkItem.tsx(InterviewContainer
渲染的孩子之一,收到InterviewContainer
的公司)
render()
const company = this.props,
uri = company.notInterviewed ? `companies/$company.id/details` : `/interviews/companies/$company.id`,
className = `margin-top-10 margin-bottom-10 $company.notInterviewed ? 'ft-company-not-interviewed' : ''`;
const link = (
<Link className=className id=company.id.toString() to=uri>
<span id="company-name">company.name</span>
</Link>
);
我想我可能需要在路由更改时重置 Redux 状态。我看到过去有人使用过LOCATION_CHANGE
,但那已经过时了,这是第三方 redux 库提供的常量,不再受支持。所以不确定如何使用 Redux v7+ 来做到这一点
所以我想我只是需要一种方法来检测位置变化,然后以某种方式更新我的反应商店以重置公司(从我的 redux 中将 company: state.company.company,
设置为 undefined行动)
【问题讨论】:
【参考方案1】:我知道这样的事情可能很麻烦。您是否尝试过以<Link to=uri state=...someState />
的形式传递链接状态。然后无论它在哪里加载,它都应该根据它重新渲染或重置道具。可能会抛出一些骨架加载器或条件渲染逻辑。
【讨论】:
我从未见过状态通过 传递。我只需从路由道具this.props.match.params;
中提取 companyId 并在我的 React Hook 中获取公司数据。并不是说它没有重新渲染,而是在初始渲染时它以某种方式显示了陈旧的公司数据。我在代码中看不到任何导致这种情况的东西,所以它必须是 react-router 和浏览器历史记录是我的猜测
哎呀。我喜欢 useParams 和 this.props.match.params 因为同样的事实。状态是声明性的,在重新渲染甚至刷新时都不会改变。有时,当您想使用参数或本地状态对道具做其他事情时,它可能不是最佳解决方案。每天对状态求和。
为了传递状态,我从文档中提取了代码<Link to= pathname: "/courses", search: "?sort=name", hash: "#the-hash", state: fromDashboard: true />
,当我希望当前道具中的一些状态传递给新的历史对象时,我发现它很有用。我几乎可以肯定 只是 history.push 而 LOCATION_CHANGE
以上是关于在将 react-router 5 与 redux 7 一起使用时,react-router <Link> 在转到新路由后不会重置状态的主要内容,如果未能解决你的问题,请参考以下文章
react-router与react-redux跳转后保存store数据(基于"react-router": "^2.8.0")
? 基于 react + react-router + redux 构建的移动端微应用
? 基于 react + react-router + redux 构建的移动端微应用