React Router v6.0.0-alpha.5 历史记录道具删除 - 在反应上下文之外导航

T-G*_*T-G 5 javascript reactjs react-router react-router-dom

根据react router最新的v6.0.0-alpha.5版本,history prop已被删除: https: //github.com/ReactTraining/react-router/releases/tag/v6.0.0-alpha.5

删除了 <Router History> 属性,并将设置/拆除侦听器 (history.listen) 的责任移至包装器组件(<BrowserRouter>、<HashRouter> 等)中。<Router> 现在是一个受控组件,它只是为应用程序的其余部分设置上下文。

使用钩子在反应上下文中导航很简单useNavigate

但是,删除历史记录会如何影响以编程方式在反应上下文之外进行导航?例如,当我们不再可以传递历史对象时,我们如何保持历史同步,以便从 redux 或 axios/http 拦截器等内部导航?当前 V5 实现: https: //reacttraining.com/react-router/web/api/Router

或者,从 v6 开始,目标是仅依赖于 React 组件内的导航?

Rya*_*nce 3

Thanks for the question, we know this is going to come up a lot. This is a common question we've gotten for years. Please be patient with us as we begin documenting all of these kinds of things, there's a lot to do!

Short answer: Typically people use thunks for async work that leads to wanting to navigate somewhere else (after a login, after a record is created, etc.). When your thunk is successful, change the state to something like "success" or "redirect" and then useEffect + navigate:

export function AuthForm() {
  const auth = useAppSelector(selectAuth);
  const dispatch = useAppDispatch();
  const navigate = useNavigate();

  useEffect(() => {
    if (auth.status === "success") {
      navigate("/dashboard", { replace: true });
    }
  }, [auth.status, navigate]);

  return (
    <div>
      <button
        disabled={auth.status === "loading"}
        onClick={() => dispatch(login())}
      >
        {auth.status === "idle"
          ? "Sign in"
          : auth.status === "loading"
          ? "Signing in..."
          : null}
      </button>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

A bit more explanation:

For example, how would we keep our history in sync in order to navigate from inside redux

We've always considered this bad practice and reluctantly provided the history objects as first-class API to stop having philosophical conversations about app state and the URL .

但今天情况有点不同了。对话不再只是哲学问题,而且与 React 最近的异步渲染、流式传输和悬念功能混合时存在一些具体的错误。为了保护 React 路由器应用程序免受 URL 同步错误的影响(开发人员对此无能为力),v6 不再公开历史对象。

希望这个解释会有所帮助:

更改 URL 是一种副作用,而不是状态。thunk 用于执行副作用,最终找出状态容器的某些状态,但本身并不用于副作用(至少这是我的理解)。

例如,您可能希望在 redux 状态更改后更改页面上的焦点。您可能不会尝试通过 redux 操作和状态始终同步和控制文档的焦点。滚动位置相同。最终,用户可以控制这些事情:他们可以按 Tab 键、单击某些内容或滚动。您的应用程序不会尝试拥有或同步该状态,它只是不时更改它以响应您控制的操作和状态

网址是一样的。用户可以在地址栏中输入任何他们想要的内容,单击后退、前进,甚至单击并按住后退按钮可后退 3 个条目!它与焦点和滚动位置的状态相同:由用户拥有。容器永远无法真正拥有 URL 状态,因为它无法控制围绕它的操作。混入 React 的新功能和即将推出的功能,你就会输掉这场游戏。

简而言之:更改 redux 状态 > UI 中的 useEffect > 导航。希望有帮助!