麻烦处理与钩子等效的setState异步函数

时间:2020-09-16 19:26:58

标签: javascript reactjs react-hooks setstate

import React from "react";
import { UserContext } from "./../contexts";
import {
  removeStoredAuthData,
  storedAuthIsValid,
  storeNewAuthData,
} from "./../utils/auth";
import { getUserInfos } from "./../api/userAuthentication";

class UserProvider extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      user: "",
    };
  }

  render() {
    return (
      <UserContext.Provider
        value={{
          user: this.state.user,
          clearUserProfile: () => {
            const user = "";
            removeStoredAuthData();
            this.setState({ user });
          },
          saveUserProfile: (response) => {
            const user = response.data;
            storeNewAuthData(response);
            this.setState({ user });
          },
          populateUserProfile: (displayLoader, hideLoader) => {
            const storedToken = localStorage.getItem("appsante-token");
            const storedId = localStorage.getItem("appsante-id");
            if (storedAuthIsValid()) {
              displayLoader(() => {
                getUserInfos(storedId)
                  .then((response) => {
                    const user = { ...response.data, token: storedToken };
                    this.setState({ user }, hideLoader());
                  })
                  .catch((error) => console.log(error));
              });
            }
          },
        }}
      >
        {this.props.children}
      </UserContext.Provider>
    );
  }
}

export default UserProvider;

大家好!

我试图将带有钩子的React类组件转换为功能组件。

但是我找不到正确处理该行的方法:

this.setState({ user }, hideLoader());

与类组件中的setState不同,useState不会将回调作为第二个参数,而且我找不到使用useEffect来实现它的方法。

有人可以帮助我吗?谢谢!

2 个答案:

答案 0 :(得分:0)

由于无法单独根据user中/的值来确定加载程序的存在,因此,您将需要另一个状态变量,也许其中包含回调-可能将其称为hideLoader。在getUserInfos解决之后,使用回调函数调用setHideLoader,以便具有该函数作为依赖项的useEffect钩子可以看到更改并调用回调函数:

const [hideLoader, setHideLoader] = useState();
useEffect(() => {
  if (hideLoader) {
    hideLoader(); // or, if this is a HOF: hideLoader()()
    setHideLoader(); // callback done; remove callback from state
  }
}, [hideLoader]);
// ...
  populateUserProfile: (displayLoader, hideLoaderParam) => {
    // ...
    getUserInfos(storedId)
      .then((response) => {
        setUser({ ...response.data, token: storedToken }); // hook version
        setHideLoader(hideLoaderParam);
      })

和您其余的代码几乎可以相同-仅在setHideLoader内部调用上方的getUserInfos

答案 1 :(得分:0)

我认为您应该这样做:-

import React, { useState } from 'react';
    
const [user, setUser] = useState("");
    
populateUserProfile: async (displayLoader, hideLoader) => {
                const storedToken = localStorage.getItem("appsante-token");
                const storedId = localStorage.getItem("appsante-id");
                if (storedAuthIsValid()) {
                  displayLoader();
                    let  response = await getUserInfos(storedId)
                    const user = { ...response.data, token: storedToken };
                    setUser(user);
                    hideLoader();
                  };
                }