React Router v6.0.0-alpha.5 历史props移除 - 在 React 上下文之外导航

IT技术 javascript reactjs react-router react-router-dom
2021-05-18 17:01:06

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

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

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

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

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

1个回答

谢谢你的问题,我们知道这会出现很多。这是我们多年来得到的一个常见问题。当我们开始记录所有这些类型的事情时,请耐心等待,还有很多工作要做!

简短回答:通常人们将 thunk 用于异步工作,这会导致想要导航到其他地方(登录后、创建记录后等)。当您的 thunk 成功时,将状态更改为类似"success""redirect",然后使用效果 + 导航:

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>
  );
}

多一点解释:

例如,我们如何保持我们的历史同步以便从 redux 内部导航

我们一直认为这是一种不好的做法,并且不情愿地将history对象作为一流的 API 提供,以停止关于应用程序状态和 URL 的哲学对话😅。

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

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

更改 URL 是副作用,而不是状态。Thunk 用于执行副作用,最终确定状态容器的某些状态,但不用于其本身的副作用(至少这是我的理解)。

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

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

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