如何在Reactjs函数式组件中使用history.push

18

我有一个包含表单的功能组件。在提交后,我想重定向到另一个页面。

function ProfileForm(props) {
 // many code removed
 const onSubmit = (data, e) => {
   e.target.reset();
   history.push({
  pathname:  "/OnSubmit",
  state: {
    response: messageFromServer 
   } 
  }
}
// many code removed
}

我遇到了这个错误:

意外使用了 'history' no-restricted-globals

在搜索了这个错误之后,我找到了一个类似于location的答案。答案是:尝试在location前添加window(即window.location)。 所以我尝试了:

  window.history.push({
  pathname:  "/OnSubmit",
  state: {
    response: messageFromServer 
  } 
}

遇到新的错误:-

未处理的拒绝(TypeError):window.history.push不是一个函数


尝试使用 window.history.pushState() - user8745435
5个回答

42

我认为你是使用react-router来处理路由。如果是这样,你需要使用通过ReactRouterContext传递的history对象。要做到这一点,你需要使用useHistory hook 来获取history对象。

// ...
import { useHistory } from "react-router";
// ...


function ProfileForm(props) {
  const history = useHistory();
  const onSubmit = (data, e) => {
     e.target.reset();
     history.push({
        pathname:  "/OnSubmit",
        state: {
          response: messageFromServer 
        } 
     });
  }
}

1
是的,它可以工作。但还有另一个问题。在此调用之前,我会发出一个post请求:axios.post('http://localhost:8080/profile', profile) .then(res => { setMessageFromServer(res.data) }).catch((error) => { // 处理这个错误 setMessageFromServer(error.data) }) 我想获取此响应并发送到OnSubmit页面。我该如何等待此响应? - masiboo
1
不了解您的路由和状态管理架构,很难推荐任何东西。您可以将状态提升到 ProfileFormOnSubmitPage 的第一个共同父级,将回调属性传递给名为 onSuccessProfileForm,并像这样使用它:axios.post('http://localhost:8080/profile', profile).then(res => { onSuccess(res.data); history.push("/onSubmit"); })...。然后,共同父级可以将此状态传递给 OnSubmitPage - Onur Önder
如果你正在使用 redux 或者 mobx,那就是另外一回事了,有很多不同的解决方案。你可以使用 contextAPI。你甚至可以简单地将数据写入 sessionStorage,重定向到 OnSubmitPage 并从存储中读取值。这完全取决于你的架构。 - Onur Önder
在React中处理API响应是一个大的话题。有简单的方法、高级的方法和“难以维护”的方法。你可以使用reduxmobx,但最近社区中的一些人正在远离它们,因为它们的复杂性和负面影响。还有一些人试图将UI状态与API状态分离。他们说像isDarkThemeisDrawerOpen这样的UI状态应该存储到一个与API响应分开的存储器中(这只是一个缓存)。你也可以查看swrreact-query。就像我说的,有很多替代方案。 - Onur Önder
谢谢,回调函数正常工作。我该如何防止用户在提交后返回?我的意思是当他在提交页面时,无法返回到ProfileForm,即使他返回也不会有任何旧数据。它应该是一个空表单。 - masiboo
显示剩余2条评论

4

不要使用history.push,尝试使用navigate替代

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

const addToCartHandler = () => {
  navigate(`/cart/${productId}?qty=${qty}`)
};

现在这应该是被接受的答案。useNavigate是一个较新的钩子,它使你的代码更直观。 - KCDC

1
请使用props.history代替
const onSubmit = (data, e) => {
   e.target.reset();
   props.history.push("/OnSubmit")
  }
}

0
你可以使用 useHistory()。以下代码可以帮助你。
import { useHistory } from "react-router";

export default function Checkout(props) {
    
const history = useHistory();
 
return (
              <React.Fragment>
                <AddressForm history ={ history} ></AddressForm>
              </React.Fragment>
        </Paper>
      </main>
    </React.Fragment>
  );
}

0
如果您在函数组件中使用了 import { withRouter } from "react-router-dom";,那么您是否忘记了添加 props.history.push 了呢?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接