ReactJS-我不理解此函数中使用的语法

时间:2018-06-25 15:00:45

标签: javascript reactjs drag-and-drop

我正在尝试了解此功能,该功能用于反应式拖放可排序列表。

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]],

我尝试查找拼接数组定义,但我只是不了解其工作原理。有人可以解释吗?

2 个答案:

答案 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]]是一个包含以下内容的数组:

  • 其中包含dragIndex1的数组
  • 其中包含hoverIndex0dragCard的另一个数组

$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;

...但是我认为那里的清晰度受到的影响非常严重。 :-)