【问题标题】:React axios request asks for UseEffect cleanup function to cancel all subscriptions and asynchronous tasksReact axios请求请求UseEffect清理函数取消所有订阅和异步任务
【发布时间】:2020-03-31 05:20:27
【问题描述】:

我正在使用 axios 从我的 API 中获取一些数据,但所有请求都不在 useEffect 函数中。甚至更多 - 我没有完全使用 useEffect。

以下是我的部分代码:

JSX:

<form onSubmit={onSubmitLogin}>
      <div className="form sign-in">
        <h2>Hello again,</h2>
        <div className="div-label">
          <label>
            <span>Email</span>
            <input type="email" onChange={onLoginEmailChange} />
          </label>
        </div>
        <div className="div-label">
          <label>
            <span>Password</span>
            <input type="password" onChange={onLoginPasswordChange} />
          </label>
        </div>
        <p className="forgot-pass">Forgot password?</p>
        {loading && (
          <img
            alt="svg"
            className="loading-img"
            align="middle"
            width={35}
            height={35}
            src={mySvg}
          />
        )}
        {!loading && (
          <input className="submit" type="submit" value="Sign In" />
        )}

所以这是调用:

    const onSubmitLogin = e => {
    e.preventDefault();
    setLoading(true);

    axios
      .get(
        `http://myapiURL/?email=${loginEmail}&password=${loginPassword}`
      )
      .then(res => {
        console.log(res);
        if (res.status === 200) {
          console.log("here");
          history.push({
            pathname: "/dashboard",
            state: res.data
          });
          setLoading(false);
        }
      })
      .catch(e => {
        console.log(e);
      });
  };

这是有效的,它给了我数据,但在浏览器中我看到了这个错误:

index.js:1375 警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。 在登录中(由 Context.Consumer 创建)

我发现了很多这方面的信息,但所有这些都与他们将请求方法放在 useEffect 中有关。
P.S.:顺便说一句,我正在使用 React 钩子(在这个组件中使用状态但不是 useEffect)

【问题讨论】:

  • 我认为问题是你在推送历史之后改变了组件的状态,所以你挂载了另一个组件并在一个未挂载的组件中改变了状态
  • 当您重定向到该页面时,您的错误可能在 /dashboard 而不是 /login 中。
  • 我同意@Sabbin
  • @Sabbin 你是对的。我把 setLoading(false);在 push 之前,没有问题了。谢谢!

标签: javascript reactjs axios react-hooks use-effect


【解决方案1】:

在您的 onSubmitLogin 上,您正在推送到另一个路径名,这会促使组件卸载,然后,您尝试从已卸载的组件更新状态(在 history.push 之后您拥有的 setLoading(false) )。

您可以在历史推送之前 setLoading(false) 或从那里删除 setLoading 并创建一个 useEffect 以在其清理周期中将加载状态设置为 false。喜欢:

useEffect(() => {
  return () => {
    setLoading(false);
  }
}, [])

useEffect 的返回将在更改为另一个组件之前执行,例如 ComponentWillUnmount 生命周期。

【讨论】:

    【解决方案2】:

    您正在为未安装的组件设置状态,因此您必须在 history.push 之前调用 setLoading

    const onSubmitLogin = e => {
        e.preventDefault();
        setLoading(true);
    
        axios
          .get(
            `http://myapiURL/?email=${loginEmail}&password=${loginPassword}`
          )
          .then(res => {
            console.log(res);
            if (res.status === 200) {
              console.log("here");
              setLoading(false);
              history.push({
                pathname: "/dashboard",
                state: res.data
              });
            }
          })
          .catch(e => {
            console.log(e);
          });
      };
    

    【讨论】:

      【解决方案3】:

      如果在异步函数完成之前卸载组件并尝试设置一些状态变量,则可能会出现此问题

      要解决此问题,您可以执行以下操作:

      React.useEffect(() => {
          let isSubscribed = true;
          axios
            .get(
              `http://myapiURL/?email=${loginEmail}&password=${loginPassword}`
            )
            .then(res => {
                console.log(res);
                if (res.status === 200) {
                  history.push({
                     pathname: "/dashboard",
                     state: res.data
                 });
                 // check if this component still mounted
                 if (isSubscribed) {
                   setLoading(false);
                 }
               }
            });
      
          return () => (isSubscribed = false);
      }, []);
      

      【讨论】:

        猜你喜欢
        • 2019-10-20
        • 2021-03-24
        • 2021-01-28
        • 1970-01-01
        • 2021-06-23
        • 2021-03-28
        • 2021-07-02
        • 1970-01-01
        • 2020-11-28
        相关资源
        最近更新 更多