在React Redux中拖放行后更新React-Table值

时间:2019-11-07 16:38:06

标签: react-redux

我已经完成了React拖放功能到我的项目中,因此我可以在React表的列表中对行进行重新排序。问题是我有一个名为“序列”的列,女巫向我显示了元素的顺序,我无法更新其值。

示例:

之前(行可拖动):

Sequence  | Name

    1       Jack
    2       Angel

之后(我需要更新Sequence的值,其中在放置特定的可拖动行之后更改其位置,在这种情况下,我将Jack拖到第一个位置,并将其拖到第二个位置):

Sequence  | Name

   1        Angel
   2        Jack

React / Redux允许我更改此元素数组的索引顺序,而不会收到“在两次派发之间检测到状态突变”错误消息,但不允许我用新的更新Sequence值订单值。

这是我到目前为止尝试过的:

    // within the parent class component 
    // item is an array of objects from child
    UpdateSequence(startIndex, endIndex, item) {

    // the state.Data is already an array of object
    const result = this.state.Data;
    const [removed] = result.splice(startIndex, 1);
    result.splice(endIndex, 0, removed);

    // this is working without the mutation state error
    this.setState({ Data: result })

    let positionDiff = 0;
    let direction = null;
    let newIndex = 0;

    positionDiff = endIndex - startIndex;
    if (startIndex > endIndex) {
        direction = "up";
    }
    else if (startIndex < endIndex) {
        direction = "down";
    }

    if (positionDiff !== 0) {
        for (var x = 0; x <= Math.abs(positionDiff); x++) {

            if (x === 0) {
                newIndex = startIndex + positionDiff - x;
                this.setState(prevState => ({
                    Data: {
                        ...prevState.Data,
                       [prevState.Data[newIndex].Sequence]: Data[newIndex].Sequence + positionDiff
                    },
                }));
            }
      else {
                if (direction === "down") {
                    newIndex = startIndex + positionDiff - x;
                    this.setState(prevState => ({
                        Data: {
                            ...prevState.Data,
                            [prevState.Data[newIndex].Sequence]: Data[newIndex].Sequence - 1
                        },
                    }));
                }
                else if (direction === "up") {
                    Data= startIndex + positionDiff + x;
                    this.setState(prevState => ({
                        Data: {
                            ...prevState.Data,
                            [prevState.Data[newIndex].Sequence]: Data[newIndex].Sequence + 1
                        },
                    }));
                }
            }
    }
        // so when i call save action i am stepping into the 'A state mutation was detected between dispatches' error message. 
        this.props.actions.saveSequence(this.state.Data)
        .then(() => {
            this.props.actions.loadData();
        })
        .catch(error => {
            toastr['error'](error, 'error....');
        })
}

每当我尝试更新数组元素“序列”时,调用操作“ saveSequence”,即得到“在两次调度之间检测到状态突变”错误消息。

任何帮助都将非常有用!谢谢!

注意:用于重新排序序列的逻辑是可以的。

2 个答案:

答案 0 :(得分:0)

虽然我不太了解redux,但我注意到您正在直接修改state,这似乎是罪魁祸首。

const result = this.state.Data;
const [removed] = result.splice(startIndex, 1);

splice是一种破坏性方法,会修改其输入,并且其输入是对this.state中某些内容的引用。

演示:

> state = {Data: [1,2,3]}
{ Data: [ 1, 2, 3 ] }
> result = state.Data.splice(0,1)
[ 1 ]
> state
{ Data: [ 2, 3 ] }

请注意,state已被修改。这可能是Redux所检测到的,也是一般的反应禁忌。

为避免修改状态,最简单的方法是克隆您要修改的数据

const result = this.state.Data.slice()

请注意,这会复制 shallow ,因此,如果Data具有非原始值,则还必须注意对这些值进行破坏性编辑。 (如果要了解更多信息,请查找深层副本与浅层副本。)但是,由于您只是重新排序商品,因此我相信您是安全的。

答案 1 :(得分:0)

好吧,我发现更改了这部分代码:

    //code....  

    const result = item;
    const [removed] = result.splice(startIndex, 1);

    // i created a new empty copy of the const 'removed', called 'copy' and update the Sequence property of the array like this below. (this code with the sequence number is just a sample of what i came up to fix it )

    let copy;
    copy = {
        ...removed,
        Sequence: 1000,
    };              

    result.splice(endIndex, 0, copy);

在我没有设置状态之后,我评论了这一行:

    // this.setState({ Data: result })

    //...code

,最后将结果作为参数而不是状态放入保存操作。

     this.props.actions.saveSequence(result)

Works,现在我可以完全拖放功能,将新订单序列保存到数据库中,而不再出现“在两次派遣之间检测到状态突变”错误消息!