根据Visual Studio或ReSharper Intellisense,散布运算符...
是实验级别的功能,我正在使用ECMAScript 2015:
我正在使用Babel,并且在已编译的源代码中看到了传播算子:
因此,我尝试用Object.assign替换用于在React状态下的对象进行更新的散布运算符功能。
使用散布运算符,我可以使用以下命令更新对象的状态:
setInputs(prevInputs => ({ ...prevInputs, [name]:value}));
这很好。现在,我想删除散布运算符,以最大程度地实现跨浏览器的兼容性。
不幸的是,当我尝试使用其他方法更新状态对象中属性的值更改时,出现错误:
一个组件将文本类型的受控输入更改为不受控制。输入元素不应从受控切换为不受控制
我理解此错误消息的含义,与扩展运算符相比,我无法理解的是对象更新的不同之处,这是我尝试替换扩展运算符的方式:
if (value) {
//try to update state with value that is not undefined
setInputs(prevInputs => Object.assign({}, prevInputs)[name] = value);
//another try to update state with value that is not undefined
setInputs(prevInputs => prevInputs[name] = value);
}
我不明白这里发生了什么,散布运算符正在创建一个新对象:
const originalObj = {
name: '',
};
const spread = {...originalObj};
console.log('is originalObj === spread', originalObj === spread); //no they are not
我的Object.assign替换价差的方式如何不会像价差运算符对象的创建那样结束?
答案 0 :(得分:1)
要模拟传播并将新属性分配给对象,您需要
(1)创建原始对象的浅表副本
(2)为该复制对象分配一个新值
(3)返回复制的对象
这样做的时候
public static class Class1
{
// simulate reading lines from file
public static List<String> SAO_Num = new List<String>() {
"test1",
"test2",
"test3",
"test4",
"test5",
"test6",
"test7",
"test8",
"test9",
"test10"
};
public static int countSAO = SAO_Num?.Count ?? 0;
}
public class Class2
{
...
button.Text = Class1.countSAO.ToString();
...
}
您要创建一个浅表副本,但随后您要返回赋值,因此返回值是赋值的值,而不是复制的对象。上面的代码等效于
setInputs(prevInputs => Object.assign({}, prevInputs)[name] = value);
最好避免在表达式中使用赋值-它们几乎永远不是您想要的。
使用
setInputs(prevInputs => value);
您正在执行一些类似的操作:对现有的setInputs(prevInputs => prevInputs[name] = value);
对象进行突变,并返回prevInputs
。等同于
value
要实现浅表复制,请在复制的对象上设置一个值,然后将其返回,请执行以下操作:
setInputs(prevInputs => {
prevInputs[name] = value;
return value;
});
或者,等效地:
setInputs(prevInputs => {
const newInputs = Object.assign({}, prevInputs); // Shallow copy
newInputs[name] = value; // Assign new value
return newInputs; // Return copied object
});
以上方法之所以有效,是因为setInputs(prevInputs => Object.assign({}, prevInputs, {[name]: value }));
返回了新对象(第一个参数)。
请记住,这避免了对象传播语法(即ES2018),从而导致代码与ES2015兼容。为了使代码与ES5(ES2009)兼容,需要做很多工作。无论哪种方式,为了使您的代码兼容,最好使用Babel自动处理它-这样可以使源文件保持美观和可读性,同时允许过时的浏览器了解已转译的代码。
答案 1 :(得分:1)