我正在尝试了解此功能,该功能用于反应式拖放可排序列表。
moveCard = (dragIndex, hoverIndex) => {
const { cards } = this.state
const dragCard = cards[dragIndex]
this.setState(
update(this.state, {
cards: {
$splice: [[dragIndex, 1], [hoverIndex, 0, dragCard]],
},
}),
)
}
特别是我听不懂这行
$splice: [[dragIndex, 1], [hoverIndex, 0, dragCard]],
我尝试查找拼接数组定义,但我只是不了解其工作原理。有人可以解释吗?
答案 0 :(得分:3)
那是immutability helper。对于数组中的每个项目,它使用该项目提供的参数在目标上调用splice()
。
例如:
const collection = [1, 2, {a: [12, 17, 15]}];
const newCollection = update(collection, {2: {a: {$splice: [[1, 1, 13, 14]]}}});
// Outputs: [1, 2, {a: [12, 13, 14, 15]}]
这将访问collection
的索引2,键a
,并在插入13和14的同时从索引1开始删除一项(删除17)。
答案 1 :(得分:1)
这是一个属性初始值设定项,它定义了一个名为$splice
的属性,其值为[[dragIndex, 1], [hoverIndex, 0, dragCard]]
。
[[dragIndex, 1], [hoverIndex, 0, dragCard]]
是一个包含以下内容的数组:
dragIndex
和1
的数组hoverIndex
,0
和dragCard
的另一个数组 $splice
属性是immutability helper:
{$splice: array of arrays}
对数组中的每个项目都使用该项目提供的参数在目标上调用splice()
。
实际上,该代码正在执行此操作:
const cards = [...this.state.cards];
cards.splice(dragIndex, 1);
cards.splice(hoverIndex, 0, dragCard);
this.setState({cards});
...这意味着它是incorrect。根据现有状态设置状态时,您必须使用回调版本setState
。我们需要更多上下文来向您展示如何使用setState
的回调版本正确地实现这一点(因为您不能依靠hoverIndex
并且dragIndex
在回调发生时仍然是正确的)。但这看起来像这样:
// This is GUESSING at several details, such as that the entries in
// `cards` are objects.
const { cards } = this.state;
const cardToRemove = cards[dragIndex];
const addInFrontOf = cards[hoverIndex];
this.setState(prevState => {
const cards = [...prevState.cards];
let index = cards.findIndex(cardToRemove);
if (index != -1) {
cards.splice(index, 1);
}
let index = addInFrontOf ? cards.findIndex(addInFrontOf) : cards.length;
cards.splice(index, 0, dragCard);
return {cards};
});
...或使用不变性帮助程序的等效项,但要注意如果dragIndex
低于hoverIndex
会发生什么情况。
请注意以下三行:
const { cards } = this.state;
const cardToRemove = cards[dragIndex];
const addInFrontOf = cards[hoverIndex];
...可能是
const {
cards: {
[dragIndex]: cardToRemove,
[hoverIndex]: addInFrontOf
}
} = this.state;
...但是我认为那里的清晰度受到的影响非常严重。 :-)