javascript - 使用数组属性设置 React 或 Recoil 状态对象的更简单方法
问题描述
希望有人可以帮助我以更简单的方式更新我在更复杂的对象/数组上的反冲状态。我主要是一名 C# 开发人员,但正在尝试学习一些不错的 javascript 编码方法。这看起来很丑陋而且过于复杂,就像我的代码目前的样子。
由于状态实例是只读的,我无法直接更改它的值。使用下划线克隆方法甚至不会改变这一点。
所以这是我的简化对象,在现实生活中有很多不相关的属性:
interface IDeviceAttributeValue {
/** The unique value key
id: string;
/** The attribute value */
value: any;
}
interface IDeviceAttribute {
/** A unique key to identify the attribute. Normally the OSC address of the setting is used */
key: string;
/** The list of attribute values */
values: IDeviceAttributeValue[];
}
在 React 我有状态声明
const [attribute, setAttribute] = useState(props.attribute as IDeviceAttribute);
或者其他地方有 Recoil 状态:const [deviceAttributeState, setDeviceAttributeState] = useRecoilState(recoilDeviceAttributeState);
在代码的某处,我需要更改值数组上的值并更新状态。在 React 状态和 Recoil 状态的两种情况下,“getter”实例都是只读/常量。
我最终得到了这个:
... code calculating a new value for existing value in editedSetting: IDeviceAttributeValue
...
// Now update state, first find the element in the array
let index = attribute.values.findIndex(l => l.id === editedSetting.id);
if (index !== -1) {
let newValueItem = {
...attribute.values[index],
value: newValue
}
setAttribute({
...attribute,
values: [...attribute.values.slice(0,index - 1), newValueItem,
...attribute.values.slice(index + 1)]
})
}
这么多行代码用于简单的状态更新!我敢肯定,对于某人来说,这是非常微不足道的任务,并且可以做得更优雅:-)
感谢您的帮助和时间
解决方案
如果这在您的代码中很常见,那么您可以将更新逻辑提取到自定义挂钩中。我在想类似的东西
function useDeviceAttribute(initialValue: IDeviceAttribute) {
const [attribute, setAttribute] = useState(initialValue);
const updateAtId = (id: number, newValue: any) => {
let index = attribute.values.findIndex(l => l.id === id);
if (index !== -1) {
let newValueItem = {
...attribute.values[index],
value: newValue
}
setAttribute({
...attribute,
values: [...attribute.values.slice(0,index - 1), newValueItem,
...attribute.values.slice(index + 1)]
})
}
};
return [attribute, updateAtId];
}
所以你的组件代码会是这样的
function YourComponent(props) {
const [attribute, updateAtId] = useDeviceAttribute(props.attribute);
//
// your component code goes here
//
// ... code calculating a new value for existing value in editedSetting: IDeviceAttributeValue
/// ...
// Now update state, first find the element in the array
updateAtId(editedSetting.id, newValue);
}
推荐阅读
- android - 数据绑定编译但在 Android Studio 3.6 中显示错误
- reactjs - Formik 数字字段仅接受正数
- python - 使用来自两列的值在 Pandas 中创建新列
- powerbi - 如何在 Power Query M 中使用 WebAction.Request?
- reactjs - 使用参数反应管理员发布查询
- html - 字体在不同浏览器中看起来不同
- javascript - 在版本 6.1.8 中单击按钮时,Revolution 滑块如何再次启动(播放)?
- powershell - 将结果输出到文件
- jestjs - 开玩笑无法读取 null 的属性“createEvent”
- terminal - 终端卡住加载 GatsbyJS “Hello-World” 入门网站