在不触发钩子和不破坏穷举依赖关系规则的情况下,以useEffect为条件更改状态



我正试图将一个突变注册为useEffect钩子中的inFlight。只有在突变尚未登记的情况下才应进行登记。因此,我在状态中有一个布尔变量来跟踪突变是否已经注册,并根据它有条件地注册。在useEffect中注册突变后,我立即将此变量设置为true。因此,在我进行注销后,我在注销突变功能中将其设置为false。

问题来了:为了遵守useEffect的穷举依赖规则,我必须在依赖数组中包含布尔状态变量。然而,这意味着一旦我注销,useEffect就会运行并重新注册突变。相反,我希望注销只是"准备"注册,然后只有在特定值更改时才进行注册。在遵守详尽无遗的依赖规则的情况下,这可能吗?

我尝试将布尔变量更改为包含三种状态(AwaitingValueChange、ShouldDispatch和HasDispatched(的ENUM,仅当其值为ShouldDisplace时才进行调度,并在注销中将该值设置为AwaitingValue change。然后,我创建了一个新的钩子,每次应该触发注册的值更改时都要运行,如果当前值为AwaitingValueChange,则将状态变量设置为ShouldDispatch。然而,新钩子也以状态变量为条件,所以我遇到了完全相同的问题,只是这次调用链是:取消注册->新钩子->旧钩子->注册,而不是取消注册->旧钩子->register。

寄存器代码:

useEffect(() => {
if (hasRegisteredMutationInFlight && inFlightDispatch) {
inFlightDispatch({ type: 'registerMutation', mutationName });
setHasRegisteredMutationInFlight(true);
}
}, [hasRegisteredMutationInFlight, ...]);

注销代码:

const deregisterMutation = () => {
inFlightDispatch({ type: 'deregisterMutation', mutationName });
setHasRegisteredMutationInFlight(false);
};

我想用某种方式设置一个状态,而不是让它触发我的useEffect,而是使用该状态在同一useEffect中有条件地执行操作。我也不想打破详尽无遗的依赖规则。对我来说,以useEffect目前的实现方式,这听起来是不可能的,但我希望这里有人比我聪明一点,可以看到一些我忽视的解决方案

不能对registerderegister突变使用相同的标志。这根本没有道理。为什么需要在deregisterMutation中使用setHasRegisteredMutationInFlight (false)?您可以取消注册,在重新注册某个值时,将标志设置为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);

相关内容

最新更新