升级到 Umi4 后,有同事和我反映,之前的一些组件不能用了,获取不到 props
,props
是空对象。
Umi4 在代码层做了修改,将 react-router@5
升级到 react-router@6
,所以路由相关的一些 api 存在着使用上的差异。
props 默认为空对象,以下属性都不能直接从 props 中取出:
需要采用下面的方式:
children
import { Outlet } from 'umi'; <Outlet />;
主要在全局 layout 中需要修改:
如 layouts/index.tsx
:
import React from 'react'; + import { Outlet } from 'umi'; export default function Layout(props) { return ( <div> - { props.children } + <Outlet /> </div> ); }
使用了 React.cloneElement
方式渲染的路由组件改造,示例
import React from 'react'; + import { Outlet } from 'umi'; export default function RouteComponent(props) { return ( <div> - { React.cloneElement(props.children, { someProp: 'p1' }) } + <Outlet context={{ someProp: 'p1' }} /> </div> ); }
组件改成从 useOutletContext
取值
import React from 'react'; + import { useOutletContext } from 'umi'; - export function Comp(props){ + export function Comp() { + const props = useOutletContext(); return props.someProp; }
history
+ import { history } from 'umi'; export default function Page(props) { return ( <div onClick={()=>{ - props.history.push('list'); + history.push('list'); }}> </div> ); }
location
建议组件或 hooks
里用 useLocation
取,其他地方就用 window.location
获取。
export default function Page(props) { + const { location } = window; return ( <div> - { props.location } + { location } </div> ); }
或者
+ import { useLocation } from 'umi'; export default function Page(props) { + let location = useLocation(); return ( <div> - { props.location } + { location } </div> ); }
match
+ import { useMatch } from 'umi'; export default function Page(props) { + const match = useMatch({ path: 'list/search/:type' }); return ( <div> - { props.match } + { match } </div> ); }
需要注意 match 数据的差异:
// match v5 isExact: true params: {} path: "/users/abc" url: "/users/abc" // match v6 params:{ } pathname: "/list/search/articles" pathnameBase: "/list/search/articles" pattern: {path: 'list/search/:type'}
更多改动和 api 变更,可参考 react-router@6
未经允许不得转载:前端资源网 - w3h5 » Umi4获取不到props,默认为空对象