ReactJS - 使用切片更新状态后,不会重新呈现视图

时间:2018-05-22 11:05:14

标签: reactjs setstate mutation

这是我在Content内呈现的班级App.js。我已经阅读了ReactJS教程,并了解我需要更改数据而不会发生变异。

https://reactjs.org/tutorial/tutorial.html

但即使我使用slice,该应用也不会重新呈现状态变化。

这个班级管理下面的一副牌:

//omitted imports
import main_deck from ...
import side_deck from ...

export default class Content extends Component {
    constructor(props) {
        super(props);
        this.moveToMainDeck = this.moveToMainDeck.bind(this);
        this.state = {
            mainDeck : main_deck,
            sideDeck : side_deck
        }
    }

    moveToMainDeck(card) {
        const fromDeck = this.state.sideDeck.slice(); //copy the state data
        const toDeck = this.state.mainDeck.slice();

        var movable = checkMovability(fromDeck, toDeck, card);
        if (movable[0] === 1) { //use slice instead of splice
            var newMain = toDeck.slice(0, movable[1]).concat([card]).concat(toDeck.slice(movable[1]));

            var cardIndexInSideDeck = fromDeck.indexOf(card);
            var newSide = fromDeck.slice(0, cardIndexInSideDeck).concat(fromDeck.slice(cardIndexInSideDeck + 1));

            this.setState({ mainDeck : newMain, sideDeck : newSide });
        }
        else if (movable[0] === -1)
            alert("Unable to move. Main Deck is full.");
        else //movable[0] === 0
            alert("Unable to move. Limit reached for this card in Main Deck.");
    }

    render() {
        return (
            <div><MainDeck ... /><SideDeck ... /></div>
        );
    }
}

使用上面的代码,我通过打印出JSON数组来测试状态数据,状态确实在this.setState之后发生了变化,但视图仍然没有重新渲染。

但是,我通过将slice()替换为push()来进行测试,所有内容都会在状态更改后重新呈现,例如:fromDeck.push(card);toDeck.push(card);

任何人都可以告诉我使用的slice有什么问题。非常感谢!

2 个答案:

答案 0 :(得分:0)

这是因为切片函数创建了一个浅拷贝,这意味着它只复制对象的结构,这进一步意味着对象的字段不会被复制,只有参考被共享,所以当您更改复制对象时,原始对象也是更改,所以当react比较差异时,它找不到,因此它不会重新渲染。

collect(b)
# A tibble: 80 x 4
# Groups:   id, attribute1 [20]
      id attribute1   type_data value_data
   <dbl>      <chr>       <chr>      <dbl>
 1     1        End upper_bound         80
 2     1      Other lower_bound         20
 3     1      Start lower_bound         20
 4     1       Test     average         50
 5     1       Test upper_bound         80
 6     1       That     average         50
 7     1       That lower_bound         20
 8     1      Those       value         40
 9    10      Start lower_bound         70
10    10       That     average        100
# ... with 70 more rows

答案 1 :(得分:0)

您可以尝试使用as suggested here

const fromDeck = JSON.parse(JSON.stringify(this.state.sideDeck))

这应创建一个全新的副本。