自定义 React Hook 中的回调

IT技术 javascript reactjs
2021-04-29 06:49:58

我有以下钩子:

function useLogin(state, url, loginMessage, callback) {
  const history = useHistory();
  const logged_in = state.user.authenticated;
  useEffect(() => {
    if (!logged_in) {history.push(url); loginMessage();}
    else callback();
  }, [logged_in])
  return logged_in;
}

function useGroupAuth(state, url, loginMessage) {
  const history = useHistory();
  let has_group_auth = false;
  state.user.available_teams.forEach(function(currentValue) {
    if (currentValue.toString().toLowerCase() === teamname.toString().toLowerCase()) {
      has_group_auth = true;
    }
  })
  useEffect(() => {
    if (!has_group_auth) {
      if (state.user.available_teams.length != 0) {
        history.push(url); loginMessage();
      }
      else
        history.push("/"); loginMessage();
    } else {
      callback();
    }
  }, [has_group_auth])
  return has_group_auth;
}

他们被用作

let loggedin = useLogin(state, "/accounts/login", teamhome2_message);
let properauth = useGroupAuth(state, ("/team/" + state.user.available_teams[0]), teamhome3_message);
useEffect(() => {
  if (loggedin)
    if (properauth)
      checkteamexists(teamname);
}, []);

问题是,即使代码可以编译,它的行为也不是我想要的。if (properauth)如果loggedin为真,我只想执行

我之前的实现有效,因为我只是使用没有任何自定义钩子的回调,例如:

  useEffect(() => {
    checklogin(function() {
      checkauth(function() {
        checkteamexists(teamname);
      })
    })
  }, []);

如初始的无钩子 useEffect 钩子中所述,我如何确保properauth除非loggedin为真否则不会执行

提前致谢。

2个回答

在您的情况下,您无法更新 useGroupAuth 值。因为它只返回一个值,所以在需要时再发送一个变量(回调)来更新/检查。useState 之类的东西

function useGroupAuth(state, url, loginMessage) {
  const history = useHistory();
  const [has_group_auth, setAuth] = useState(false);

  const validate = () => {
    setAuth(
      state.user.available_teams.some(
        (currentValue) =>
          currentValue.toString().toLowerCase() ===
          teamname.toString().toLowerCase()
      )
    );
  };


  useEffect(validate, []);

  useEffect(() => {
    if (!has_group_auth) {
      if (state.user.available_teams.length != 0) {
        history.push(url);
        loginMessage();
      } else history.push("/");
      loginMessage();
    } else {
      callback();
    }
  }, [has_group_auth]);

  return [has_group_auth, validate];
}

利用

let [properauth, reValidate] = useGroupAuth(state, ("/team/" + state.user.available_teams[0]), teamhome3_message);


useEffect(() => {
  if (loggedin){
    // Do something
    reValidate();
  }
}, []);

您的useEffect钩子中似乎缺少依赖项这两个loggedinproperauthteamname为好,真的)在效果回调引用的,所以他们应该被包含在演出的依赖性。

const loggedin = useLogin(state, "/accounts/login", teamhome2_message);
const properauth = useGroupAuth(state, ("/team/" + state.user.available_teams[0]), teamhome3_message);

useEffect(() => {
  if (loggedin && properauth && teamname) {
    checkteamexists(teamname);
  }
}, [loggedin, properauth, teamname]);