reactjs 重定向至“使用React Router v6从 Saga 路由”诊断树

kr98yfug  于 2023-01-02  发布在  React
关注(0)|答案(3)|浏览(141)

我正在使用redux Saga & react路由器v6,我想从我的一个saga重定向到一个路由,有办法做到吗?

s6fujrry

s6fujrry1#

有多种选择
1-将导航方法作为已调度redux操作的一部分发送

// component
const navigate = useNavigate()
dispatch({type: FOO, navigate})

// saga
yield takeEvery(FOO, function*(action) {
  action.navigate('/foo')
})

优点:

  • 您正在使用React路由器团队推荐的navigate方法
  • API不太可能发生变化

缺点

  • 您只能在接收到此类操作的特定传奇中访问navigate方法
  • 操作中存在不可序列化的数据

2-另一种选择是以某种方式存储navigate方法。例如,您可以创建一个虚拟react组件,它将通过useNavigate钩子获取navigation方法,然后将其存储在某个"全局"变量中。请参阅以下SO答案以了解可能的解决方案:https://stackoverflow.com/a/70002872/2347716
这解决了上一个解决方案的缺点,但仍然存在一些问题:

  • 在访问navigate方法之前,您需要至少呈现一次React树
  • 您通过引入虚拟组件向视图图层添加了非视图复杂性

3-还有另一个解决方案,类似于我们在react-router 5中使用的解决前一个解决方案中的问题的方法。它使用history对象。由于它不稳定,因此没有文档记录,但是有一个HistoryRouter实现作为react-router-dom包的一部分。请参见https://github.com/remix-run/react-router/releases/tag/v6.1.1

import {unstable_HistoryRouter as HistoryRouter} from 'react-router-dom'
import { createBrowserHistory } from "history";
const history = createBrowserHistory()

// saga setup
sagaMiddleware.runSaga(rootSaga, history);

// react
<HistoryRouter history={history} />

这个解决方案的问题是它不稳定,因为它可能有一些问题与一些React18的功能。个人而言,我更喜欢它,因为它解决了一切,我们可以处理React18的问题,一旦它实际上释放,我们知道他们是什么。

bybem2ql

bybem2ql2#

我的解决方案

// "HistoryRouter" implementation
import * as React from 'react'
import type {BrowserHistory} from 'history'
import {Router} from 'react-router-dom'

export interface HistoryRouterProps {
    history: BrowserHistory
    basename?: string
    children?: React.ReactNode
}

export function HistoryRouter({
    basename,
    children,
    history,
}: HistoryRouterProps) {
let [state, setState] = React.useState({
    action: history.action,
    location: history.location,
})

React.useLayoutEffect(() => history.listen(setState), [history])

return (
    <Router
         basename={basename}
         children={children}
         location={state.location}
         navigationType={state.action}
         navigator={history}
   />
)
}

// Use
import {createBrowserHistory} from 'history'
export const history = createBrowserHistory()

ReactDOM.render(
   <HistoryRouter history={history}>
       <Routes>
           <Route path="login" element={<LoginComponent />} />
           <Route path="register" element={<RegisterComponent />} />
           <Route path="*" element={<HomeComponent />} />
      </Routes>
   </HistoryRouter>
, root)

// call history push in file saga
function* fetchLoginSaga(action: FetchLoginRequest) {
    try {
         yield call(history.push, "/home")
    } catch (e: any) {
    
    }
}
mpbci0fu

mpbci0fu3#

你可以使用**@lagunovsky/redux-react-router代替连接的react路由器**因为它支持react路由器v6 ve

相关问题