在AXIOS POST期间取消useEffect中的订阅和异步任务

时间:2019-12-05 03:33:22

标签: reactjs asynchronous axios

我执行以下代码时收到以下错误。

我想基本上设置一些在此“ RFC”文件的“呈现”中使用的属性,以便它可以在必要时更新。

错误:

无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要修复,请取消使用useEffect清理功能中的所有订阅和异步任务。

代码:

function Login() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [token, setToken] = useState('');
  const [error, setError] = useState(false);
  const [errorMsg, setErrorMsg] = useState('');
  const [isLoading, setIsLoading] = useState('');
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  async function onSubmit(e) {
    e.preventDefault();

    setIsLoading(true);

    await api.post(urls.LOGIN, {
      email,
      password
    }).then(handleSuccess.bind(this))
      .catch(handleError.bind(this))
      .finally(handleAlways.bind(this));
  }

  function handleSuccess(response) {
    setError(false);
    setErrorMsg('');
    setIsLoggedIn(true);
    setToken(response.data.token);
  }

  function handleError(e) {
    setError(true);
    setErrorMsg(e.response.data.message);
    setIsLoggedIn(false);
    setToken('');
  }

  function handleAlways() {
    setIsLoading(false);
  }

  function onChangeEmail(value) {
    setError(false);
    setErrorMsg('');
    setEmail(value);
  }

  return (
    <div className="page">
      {isLoggedIn ? <Redirect to="/" /> : <form></form> }
    </div>
  );
}

用法:

{isLoggedIn ? <Redirect to="/" /> : <form blablabla...</form>}

1 个答案:

答案 0 :(得分:0)

/* Previous:

  // Form state
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  // Auth state
  const [token, setToken] = useState('');
  const [error, setError] = useState(false);
  const [errorMsg, setErrorMsg] = useState('');
  const [isLoading, setIsLoading] = useState('');
  const [isLoggedIn, setIsLoggedIn] = useState(false);
*/

/* New
  This uses objects so order of updates doesn't matter.

  For example, in previous implementation setting logged
  and then setting loading causes an error, because updating logged
  causes a redirect and component is unmounted.

  By grouping state into domains using an object, rather than individual
  useState()'s, you can update it all at once
  and not have to worry about which order you can update state variables in.
*/

const [formState, setFormState] = useState({ email: '', password: '' })

const [authState, setAuthState] = useState({
  token: '',
  error: '',
  errorMsg: '',
  isLoading: false,
  isLoggedIn false
})

// Example usage

setAuthState({
  ...authState,
  error: 'Some error msg'
})