我是第一次接触immutablejs,并且已经设法更新了存储在对象数组中的对象的属性。我的目标是简化我的开发,但我觉得我让它变得更复杂了。显然,我遗漏了一些让事情变得更简单的东西。
我创建了堆叠闪电战项目,其中一个项目的代码没有immutablejs https://stackblitz.com/edit/react-before-immutable,另一个项目的代码没有immutablejs https://stackblitz.com/edit/react-after-immutable。
(下面的代码也是)。
我在这里看到过一些使用findIndex的第二个参数的示例,但从未为我调用过该函数。它也不在文档中,所以我猜它不再被支持了。
使用Immutable.js
import React, { useState } from 'react';
import { List } from 'immutable';
export default () => {
const init = [{
id: 101,
interestLevel: 1
},
{
id: 102,
interestLevel: 0
}];
const [myArray, setMyArray] = useState(init);
const updateRow = (e) => {
const id = parseInt(e.target.attributes['data-id'].value);
const immutableMyArray = List(myArray);
const index = List(myArray).findIndex((item) => {
return item.id === id;
});
const myRow = immutableMyArray.get(index);
myRow.interestLevel++;
const newArray = immutableMyArray.set(index, myRow);
setMyArray(newArray);
};
return (
<ul>
{
myArray.map(function (val) {
return (
<li key={val.id}>
<button onClick={updateRow} data-id={val.id} >Update Title</button>
{val.id} : {val.interestLevel}
</li>
)
})
}
</ul>
)
}
不使用Immutable.js
import React, { useState } from 'react';
export default () => {
const init = [{
id: 101,
interestLevel: 1
},
{
id: 102,
interestLevel: 0
}];
const [myArray, setMyArray] = useState(init);
const updateRow = (e) => {
const id = e.target.attributes['data-id'].value;
const newMyArray = [...myArray];
var index = newMyArray.findIndex(a=>a.id==id);
newMyArray[index].interestLevel = myArray[index].interestLevel + 1;
setMyArray(newMyArray);
}
return (
<ul>
{
myArray.map(function (val) {
return (
<li key={val.id}>
<button onClick={updateRow} data-id={val.id} >Update Title</button>
{val.id} : {val.interestLevel}
</li>
)
})
}
</ul>
)
}
发布于 2018-12-24 23:18:00
你有没有考虑过不变的目的?
在您的示例中,您只是向代码添加了不必要的复杂性,而没有利用库提供的收益。
immutable的目的是提供受scala启发的不可变集合。换句话说,您创建了自己的集合,然后将其传递给另一个组件,您可以确定没有附加或删除任何元素。然而,个别元素不在这样的保证之下,部分原因是JS带来的约束(或缺乏约束)。
在您的代码中,几乎没有理由这样做。我冒然更改了您的报价,以展示如何做到这一点:
class Comp extends React.Component {
constructor(props) {
super(constructor);
if (props.interests) {
this.state = {
interests: props.interests
}
} else {
this.state = {
interests: Immutable.Set([])
}
}
}
updateRow(e) {
return function() {
this.setState({
interests: this.state.interests.update((elements) => {
for (var element of elements) {
if (element.id == e) {
element.interestLevel++;
}
}
return elements;
})
});
}
}
render() {
var interests = this.state.interests;
var updateRow = this.updateRow;
var list = this;
//return (<div>Test</div>);
return ( <
ul > {
interests.map(function(val) {
return ( <
li key = {
val.id
} >
<
button onClick = {
updateRow(val.id).bind(list)
}
data-id = {
val.id
} > Update Title < /button> {
val.id
}: {
val.interestLevel
} <
/li>
)
})
} <
/ul>
)
}
}
var interests = Immutable.Set([{
id: 1,
interestLevel: 0
},
{
id: 2,
interestLevel: 0
}
])
ReactDOM.render( < Comp interests = {
interests
}
/>, document.getElementById("app"));
<script src="https://cdn.jsdelivr.net/npm/immutable@4.0.0-rc.12/dist/immutable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.7.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.7.0/umd/react-dom.production.min.js"></script>
<div id='app'></div>
更改:
prop
的其余更改。这意味着您可以传递一个Set
,并确保它不会在组件Set
上调用update
函数。通过render()
将所有内容呈现为一个数组
这既更具可读性,也更易于管理。
发布于 2018-12-25 04:36:03
正如您在这篇comment中提到的,您正在寻找使用Immutable.js更新深层对象层次结构中的对象的更简单的方法。
updateIn应该可以做到这一点。
const immutableObject = Immutable.fromJS({ outerProp: { innerCount: 1 } });
immutableObject.updateIn(['outerProp', 'innerCount'], count => count + 1);
还值得注意的是,您可能希望调用Immutable.fromJS()
而不是使用Immutable.List()
,因为后者不会将您的JavaScript对象深度转换为不可变对象,如果您假设数据结构是深度不可变的,这可能会导致错误。切换上面的代码以使用Immutable.fromJS()
和updateIn
,我们得到:
// In updateRow
const immutableMyArray = fromJS(myArray);
const index = immutableMyArray.findIndex((item) => {
return item.id === id;
});
const newArray = immutableMyArray.updateIn([index, 'interestLevel'], interestLevel => interestLevel + 1);
setMyArray(newArray);
https://stackoverflow.com/questions/53918086
复制相似问题