reactjs - 如何使用 React Hook useState 存储函数类型(例如箭头函数)的值?
问题描述
在 Javascript 和 Typescript 中,(箭头)函数应该是一等公民。因此,我希望我可以在我的 React 状态下拥有函数类型。但是,React HookuseState
似乎不能很好地处理函数类型。
我有以下代码:
import React, { useState } from "react";
function callApi(num: number): number {
console.log(`Api called with number ${num}. This should never happen.`);
return num;
}
type Command = () => number;
function Foo() {
const [command, setCommand] = useState<Command>();
console.log(`command is ${command}.`);
// ####################
const handleButtonClick = () => {
console.log("Button clicked.");
const myCommand = () => callApi(42);
setCommand(myCommand);
};
// ####################
return (
<div>
<button onClick={handleButtonClick}>Change state</button>
</div>
);
}
export default Foo;
当我访问该页面并单击按钮时,我得到以下控制台输出:
command is undefined.
Button clicked.
Api called with number 42. This should never happen.
command is 42.
因此,可以看到虽然在我的按钮处理程序中,状态变量command
应该设置为一个新的箭头函数,但 React 并没有这样做。相反,它执行新的箭头函数并将结果存储在状态变量中。
为什么会这样?如何在 React 状态下存储函数,而不必使用一些不方便的包装对象?
对于上下文:通常通过各种用户输入来构建某些命令功能并将它们存储在状态中以供以后使用会很方便,例如在构建作业队列时。
解决方案
为什么会这样?如何在 React 状态下存储函数,而不必使用一些不方便的包装对象?
为什么?
ReactuseState
接受一个函数(它将用作获取状态当前值的回调)或一个值,因此如果您传递() => callApi(42)
它,它将理解它就像您希望新状态成为callApi
传入时的返回值一个42
。
你能做什么?
如果你真的需要这样做(在状态中存储一个函数),你可以做类似useCommand(() => myCommand)
.
但是,我建议您不要将函数存储在组件的状态中。
如果您在代码中的某些内容发生更改时需要函数的新实例(或新函数),请使用useCallback
oruseMemo
代替。
无论何时更改依赖项数组中指定的值之一,都将创建一个新函数。
useCallback
当它们的依赖关系发生变化时将创建一个新函数,因此您可以像这样使用它:
function Button() {
const [buttonAction, setButtonAction] = useState(null);
// dynamicHandler will be a new function every time buttonAction changes
const dynamicHandler = useCallback(() => {
// Logic here based on the buttonAction value
}, [buttonAction]);
const handleClick = () => {
setButtonAction(BUTTON_ACTIONS.DO_SOMETHING);
};
return (
<button onClick={handleClick} />
);
}
查看useCallback
文档。
推荐阅读
- avi - SubRip、AVISubDetector、AviSynth 中的 RGB24 错误
- angular - 错误 TS2740:类型“可观察”
' 缺少类型 'ProjectPage[]' 的以下属性:length、pop、push、concat 和另外 25 个 - sql - Postgresql 更新非标签视图列
- php - 根据 PHP 中的项目哈希从会话中删除项目
- javascript - Big-O for while 循环没有预定义的迭代次数
- javascript - 用于包含 Express 数据库条目的按钮
- vim - 地图
在 vim 中表现不同 - postgresql - 使用 psql 从 csv 文件复制时,空列的 "" 会生成错误而不是 null
- react-navigation - 标题插入太大,即使我使用带有“react-native-safe-area-context”提供的插入的“forceInset”道具?
- javascript - 每次我将数据添加到 Firestore 时,数据条目的数量都会增加