【问题标题】:React Router v6.0.0-alpha.5 history prop removal - navigating outside of react contextReact Router v6.0.0-alpha.5 历史道具删除 - 在反应上下文之外导航
【发布时间】:2020-09-03 14:56:47
【问题描述】:

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

删除了 属性并移动了设置的责任 将侦听器(history.listen)向上/拆除到包装器中 组件( 等)。 现在是一个 只为其余部分设置上下文的受控组件 应用程序。

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

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

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

【问题讨论】:

  • 你是怎么解决这个问题的?
  • @DKo 我没有解决它,我正在探索 v6,看看我需要对 v5 上的当前应用程序进行哪些更改。我的实验时间用完了,只好继续前进。当 v6 发布时,我希望它与历史 API 一起开箱即用,或者有一个实用的解决方案。

标签: javascript reactjs react-router react-router-dom


【解决方案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 是一种副作用,而不是状态。 Thunks 用于执行副作用,最终找出状态容器的某些状态,但不用于其本身的副作用(至少这是我的理解)。

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

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

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

【讨论】:

  • 谢谢,瑞恩。感谢信息丰富的回复。
【解决方案2】:

我为我的登录重定向解决了这个问题,方法是在我的 LoginForm UI 组件中创建一个导航挂钩,然后将它传递给我的登录操作创建者,并在登录端点成功返回时调用它。也就是说……

import React from 'react'
import {useNavigate} from 'react-router-dom'

function LoginForm (props) {
    // create your navigate hook in your UI component
    const navigate = useNavigate()

    // other stuff...

    handleLogin (loginFields) {
       // then pass it into your action file, and call it 
       // when the query returns a successful result
       dispatch(login(loginFields, navigate))
    }

    // other stuff, and return statement...
}

【讨论】:

    猜你喜欢
    • 2021-01-19
    • 2019-02-06
    • 2018-08-07
    • 2018-01-02
    • 2017-08-08
    • 2017-05-22
    • 1970-01-01
    • 2017-08-12
    • 2019-05-09
    相关资源
    最近更新 更多