我正在尝试将一个突变注册为useEffect挂钩中的InFlight。仅当尚未注册突变时才应进行注册。因此,我有一个状态为boolean的布尔变量来跟踪是否已经注册了该突变,并根据该条件有条件地进行了注册。在将突变注册到useEffect中之后,立即将此变量设置为true。因此,我在注销后立即在注销注销突变函数中将其设置为false。
问题来了:为了遵守useEffect的详尽依赖规则,我必须在依赖数组中包含布尔状态变量。但是,这意味着我注销后,useEffect将运行并重新注册该突变。相反,我希望注销简单地“准备”进行注册,然后仅在特定值更改后才进行注册。遵守详尽的依赖性规则是否有可能?
我尝试将布尔变量更改为包含三个状态(AwaitingValueChange,ShouldDispatch,HasDispatched)的ENUM,仅在其值是ShouldDispatch时才分派,并在注销中将值设置为AwaitingValueChange。然后,我创建了一个新的挂钩,每次应触发注册的值更改时都将运行,如果状态变量的当前值为AwaitingValueChange,则将状态变量设置为ShouldDispatch。但是,新钩子也以状态变量为条件,所以我遇到了完全相同的问题,这一次调用链周围是:注销->新钩子->旧钩子->注册而不是注销->旧钩子->注册。
注册码:
useEffect(() => {
if (hasRegisteredMutationInFlight && inFlightDispatch) {
inFlightDispatch({ type: 'registerMutation', mutationName });
setHasRegisteredMutationInFlight(true);
}
}, [hasRegisteredMutationInFlight, ...]);
注销代码:
const deregisterMutation = () => {
inFlightDispatch({ type: 'deregisterMutation', mutationName });
setHasRegisteredMutationInFlight(false);
};
我想要一种设置状态的方法,不是让它触发我的useEffect,而是使用该状态在相同的useEffect中有条件地执行操作。我也不想破坏详尽的依赖规则。对我来说,使用useEffect的当前实现听起来是不可能的,但是我希望这里的某人比我聪明一点,并且可以看到我忽略的一些解决方案
答案 0 :(得分:1)
您不能对register
和deregister
突变使用相同的标志。这根本没有意义。为什么需要在setHasRegisteredMutationInFlight (false)
中使用deregisterMutation
?您可以注销,然后在重新注册某个值时将标志设置为false,以使其不依赖于相同的值。只是我的意思的一个有效例子
您还可以让我知道您要满足的特定用例,以便我可以为您提供更多帮助
import React, { useEffect, useCallback, useState } from "react";
import ReactDOM from "react-dom";
const mutationName = "MUTATION_NAME";
function App() {
const [type, setType] = useState("");
const [isMutationSet, setMutationToRegister] = useState(true);
const inFlightDispatch = useCallback(
stuff => {
setType(stuff.type);
},
[setType]
);
useEffect(() => {
if (isMutationSet && inFlightDispatch) {
inFlightDispatch({ type: "registerMutation", mutationName });
setMutationToRegister(false);
}
}, [isMutationSet, inFlightDispatch]);
const deregisterMutation = () => {
inFlightDispatch({ type: "deregisterMutation", mutationName });
};
const registerMutation = () => {
setMutationToRegister(true);
};
return (
<div className="App">
{type}
<button onClick={deregisterMutation}>Degister</button>
<button onClick={registerMutation}>Register</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);