React Hook useEffect 缺少依赖项:xxx。包含它们或删除依赖项数组react-hooks/exhaustive-deps

Par*_*och 8 infinite-loop reactjs use-effect

useEffect我正在从hook进行 api 调用

function ChangePassword(props) {
    const token = props.match.params.token;

    const [state, setState] = useState({
        password: "",
        confirmPassword: "",
    });
    const [status, setStatus] = useState({
        loaded: false,
        auth: false,
    });

    useEffect(() => {
        let { auth } = status;

        axios
            .get(
                `http://localhost:2606/api/hostler/changepassword?token=${token}`
            )
            .then((res) => {
                console.log("res", res);
                auth = res.status === 202;
            })
            .then(() => setStatus({ auth, loaded: true }))
            .catch((err) => console.log("err", err));
    },[]);

    return (
        // code
    );
}
Run Code Online (Sandbox Code Playgroud)

但反应发出警告

React Hook useEffect 缺少依赖项:“状态”和“令牌”。包含它们或删除依赖项数组react-hooks/exhaustive-deps

添加status到依赖数组也会导致无限循环,因为setStatus在 useEffect 内部调用

Dre*_*ese 10

如果您希望效果在组件安装时仅运行一次,那么指定空依赖项数组在技术上是正确的。然而,React-hooks linting 规则无法区分这种情况。您可以专门针对该行禁用该规则。

我还注意到,你的效果并不真正依赖于,status.auth因为你总是在改变/覆盖它,你可以删除它并只设置新的auth状态值。

useEffect(() => {
  axios
    .get(
      `http://localhost:2606/api/hostler/changepassword?token=${token}`
    )
    .then((res) => {
      console.log("res", res);
      setStatus({ auth: res.status === 202, loaded: true })
    })
    .then(() => )
    .catch((err) => console.log("err", err));

  // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
Run Code Online (Sandbox Code Playgroud)

但是,禁用该规则可能会掩盖未来的更新,因此您需要将其token作为依赖项包含在内。如果组件重新渲染/重新安装并且令牌已更改,您将需要确保使用的是最新值。换句话说,您不想使用过时的状态/属性值。

useEffect(() => {
  axios
    .get(
      `http://localhost:2606/api/hostler/changepassword?token=${token}`
    )
    .then((res) => {
      console.log("res", res);
      setStatus({ auth: res.status === 202, loaded: true })
    })
    .then(() => )
    .catch((err) => console.log("err", err));

}, [token]);
Run Code Online (Sandbox Code Playgroud)

如果您只想在auth为 false 时运行 GET 请求,那么它将是一个依赖项,应该包含在内。因此,如果解析为 false,则不会渲染循环res.status === 202,还包括尚未完成加载的条件。

useEffect(() => {
  !auth && !loaded && axios
    .get(
      `http://localhost:2606/api/hostler/changepassword?token=${token}`
    )
    .then((res) => {
      console.log("res", res);
      setStatus({ auth: res.status === 202, loaded: true })
    })
    .then(() => )
    .catch((err) => console.log("err", err));

}, [auth, loaded, token]);
Run Code Online (Sandbox Code Playgroud)