为什么在 React 上下文中存储超时不起作用?
Why does storing a timeout in React context not work?
在我的根组件中,我有一个用于跟踪 API 密钥的上下文,该密钥每隔一段时间就会过期一次:
function App() {
const [apiKey, setApiKey] = useState("");
const [timeout, setTimeout] = useState(null);
const apiKeyContextValue = {
apiKey,
setKey: setApiKey,
timeout,
setTimeout
};
return (
<apiKeyContext.Provider value={apiKeyContextValue}>
<ApiKeyForm/>
</apiKeyContext.Provider>
);
我从 ApiKeyForm
设置了 api 键,用户只需输入一个 API 键;但是,我还想设置一个超时,一旦超时就会重置 apiKeyContextValue.apiKey
:
const ApiKeyForm = ()=>{
const apiKeyContext = useContext(ApiKeyContext);
const handleSubmit = e => {
//sets api key = to value in form input
apiKeyContext.setKey(e.target[0].value);
//dummy debug code for now
apiKeyContext.setTimeout(()=>{
alert('should wipe api key now');
}, 1000)
}
return (<form onSubmit={handleSubmit}>
...
</form>)
}
我的问题是,当我提交表单时,我立即收到来自 setTimeout 的警报。为什么会这样,我该如何解决?
您从上下文中获取的 setTimeout
标识符是一个 状态 setter,而不是标准的 window.setTimeout
函数。当您将函数传递给状态 setter 时,您使用的是状态 setter 的回调形式,它将传递状态中最多 up-to-date 的值作为参数 - 例如
setSomeStateValue(mostUpToDateStateValue => {
// code that relies on mostUpToDateStateValue
这将 运行 立即。您的代码也是如此,只是变量名称不同。
在上下文状态下有 timeout
和 setTimeout
似乎对您没有任何帮助。如果您只想将状态设置为超时 ID,稍后可以 clearTimeout
调用它,请执行:
const [timeoutId, setTimeoutId] = useState(null);
传下来,然后做
apiKeyContext.setTimeoutId( // this references the state setter from context
setTimeout(() => { // this references window.setTimeout
alert('should wipe api key now');
}, 1000)
);
如果您实际上不需要在上下文中存储超时 ID,那么您可以将其完全删除并在 ApiKeyForm 中执行:
setTimeout(() => { // this references window.setTimeout
alert('should wipe api key now');
}, 1000)
在我的根组件中,我有一个用于跟踪 API 密钥的上下文,该密钥每隔一段时间就会过期一次:
function App() {
const [apiKey, setApiKey] = useState("");
const [timeout, setTimeout] = useState(null);
const apiKeyContextValue = {
apiKey,
setKey: setApiKey,
timeout,
setTimeout
};
return (
<apiKeyContext.Provider value={apiKeyContextValue}>
<ApiKeyForm/>
</apiKeyContext.Provider>
);
我从 ApiKeyForm
设置了 api 键,用户只需输入一个 API 键;但是,我还想设置一个超时,一旦超时就会重置 apiKeyContextValue.apiKey
:
const ApiKeyForm = ()=>{
const apiKeyContext = useContext(ApiKeyContext);
const handleSubmit = e => {
//sets api key = to value in form input
apiKeyContext.setKey(e.target[0].value);
//dummy debug code for now
apiKeyContext.setTimeout(()=>{
alert('should wipe api key now');
}, 1000)
}
return (<form onSubmit={handleSubmit}>
...
</form>)
}
我的问题是,当我提交表单时,我立即收到来自 setTimeout 的警报。为什么会这样,我该如何解决?
您从上下文中获取的 setTimeout
标识符是一个 状态 setter,而不是标准的 window.setTimeout
函数。当您将函数传递给状态 setter 时,您使用的是状态 setter 的回调形式,它将传递状态中最多 up-to-date 的值作为参数 - 例如
setSomeStateValue(mostUpToDateStateValue => {
// code that relies on mostUpToDateStateValue
这将 运行 立即。您的代码也是如此,只是变量名称不同。
在上下文状态下有 timeout
和 setTimeout
似乎对您没有任何帮助。如果您只想将状态设置为超时 ID,稍后可以 clearTimeout
调用它,请执行:
const [timeoutId, setTimeoutId] = useState(null);
传下来,然后做
apiKeyContext.setTimeoutId( // this references the state setter from context
setTimeout(() => { // this references window.setTimeout
alert('should wipe api key now');
}, 1000)
);
如果您实际上不需要在上下文中存储超时 ID,那么您可以将其完全删除并在 ApiKeyForm 中执行:
setTimeout(() => { // this references window.setTimeout
alert('should wipe api key now');
}, 1000)