react-router v6新特性

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react-router v6新特性相关的知识,希望对你有一定的参考价值。

参考技术A

官网文档: https://reactrouterdotcom.fly.dev/

1.废弃exact
2.component/render被element替代
3.routeProps可以在element中直接获取
4.简化的路径匹配,仅支持动态:id样式参数和*通配符,不再支持RegExp

1.支持相对路径
2.<Route> 标签支持嵌套,可以在一个文件内配置嵌套路由,便于统一管理路由
3.结合新API Outlet实现嵌套路由

注意: 嵌套路由场景 ,需要在父路由的组件(Bar)使用 Outlet 组件,用于渲染子路由

同理,配置化使用嵌套路由,Outlet 也是必要的

注意: 入口文件需要添加Router包裹App组件,否则会报错
(可以理解为,useRoutes返回的相当于Routes标签下的内容)

参考文献
https://reactrouterdotcom.fly.dev/
https://blog.csdn.net/weixin_40906515/article/details/104957712
https://zhuanlan.zhihu.com/p/434128579
https://juejin.cn/post/7025418839454122015

在将 react-router 5 与 redux 7 一起使用时,react-router <Link> 在转到新路由后不会重置状态

【中文标题】在将 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 之前的版本。

此示例中的问题在于&lt;Route component=withTracker(InterviewContainer) path="/interviews/companies/:companyId" /&gt;&lt;Link/&gt;

这是我的场景:

    主页加载了公司链接列表 点击公司&lt;Link /&gt;,它将我路由到/interviews/companies/:companyId 页面加载正常,我看到了该特定公司的图片等 点击浏览器的返回按钮 点击另一个公司 &lt;Link /&gt; 指向不同的 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.tsxInterviewContainer渲染的孩子之一,收到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】:

我知道这样的事情可能很麻烦。您是否尝试过以&lt;Link to=uri state=...someState /&gt; 的形式传递链接状态。然后无论它在哪里加载,它都应该根据它重新渲染或重置道具。可能会抛出一些骨架加载器或条件渲染逻辑。

【讨论】:

我从未见过状态通过 传递。我只需从路由道具this.props.match.params; 中提取 companyId 并在我的 React Hook 中获取公司数据。并不是说它没有重新渲染,而是在初始渲染时它以某种方式显示了陈旧的公司数据。我在代码中看不到任何导致这种情况的东西,所以它必须是 react-router 和浏览器历史记录是我的猜测 哎呀。我喜欢 useParams 和 this.props.match.params 因为同样的事实。状态是声明性的,在重新渲染甚至刷新时都不会改变。有时,当您想使用参数或本地状态对道具做其他事情时,它可能不是最佳解决方案。每天对状态求和。 为了传递状态,我从文档中提取了代码&lt;Link to= pathname: "/courses", search: "?sort=name", hash: "#the-hash", state: fromDashboard: true /&gt;,当我希望当前道具中的一些状态传递给新的历史对象时,我发现它很有用。我几乎可以肯定 只是 history.push 而 是 history.replace。 对我来说似乎很老套,抱歉。我不应该做任何花哨的事情来解决这个链接问题 IMO 我应该补充一点,我正在使用 redux。而且我搜索了你必须有某种方法来重置 redux 状态,而不是使用来自现在已过时的特殊 redux-router 库的LOCATION_CHANGE

以上是关于react-router v6新特性的主要内容,如果未能解决你的问题,请参考以下文章

React-Router v6 新特性解读及迁移指南

react-router v6新特性

react-router v6对比react-router v5

React-router v6 该怎么用?

从 react-router 迁移到 react-router v6

2021 react-router v6 快速入门