2015-12-10 48 views
0

當更改通過道具傳遞的數組長度時,'shouldComponentUpdate'函數無法檢測到數組長度更改。 我知道'shouldComponentUpdate'無法檢測到嵌套對象屬性的變化,但這是一個簡單的數組長度!這是React中的一個錯誤嗎?React shouldComponentUpdate不檢測數組長度變化?

https://jsfiddle.net/ashraffayad/cLz1q8sv/

var ArrTest = React.createClass({ 
    render: function() { 
    return <div >{this.props.arr}< /div>; 
    }, 
    shouldComponentUpdate: function(nextProps) { 
    console.log(this.props.arr.length, nextProps.arr.length); // same length !!! 
    return true; 
    } 
}); 

// - - - - app component 
var App = React.createClass({ 
    getInitialState: function() { 
    return { 
     arr: [1, 2, 3, 4] 
    }; 
    }, 
    render: function() { 
    return <ArrTest arr={ this.state.arr } />; 
    }, 
    componentDidMount: function() { 
    var self = this; 
    setTimeout(function() { 
     self.state.arr.push(7); 
     self.setState(self.state); 
    }, 2000); 
    } 

}); 

ReactDOM.render(< App /> , 
    document.getElementById('container') 
); 

回答

2

這不是在反應的錯誤,這是你的代碼的問題。 您不應該直接修改this.state值。

試試這個:

componentDidMount: function() { 
    var self = this; 
    setTimeout(function() { 
     self.setState({arr: self.state.arr.concat([7])}); 
    }, 2000); 
    } 

它的工作原理。因爲React在將道具傳遞給它時不克隆道具,所以對數組的更改會反映它的所有引用。

我建議你閱讀更多關於Javascript的不變性。

總之,永遠不要做this.state.[anything].push/pop/shift/unshift(),永遠不要。 做這樣的事情,而不是:

var arr = this.state.arr.slice(); // Create a copy of the array 
arr.push(2); // do whatever you want to do 
this.setState({ arr: arr }); // pass changes to React 
1

僅僅因爲你有兩個引用(this.props.arrnextProps.arr)並不意味着你有兩個實例

當您用push對數組進行變異時,可以修改實例。當運行shouldComponentUpdate時,它會比較引用,並且由於它們指向相同的實例,所以數組長度相同。

如果要傳遞具有不同元素或屬性的新數組,則還需要創建一個新數組。

push替換爲concat是相當容易的。

setTimeout(function() { 
    self.setState({ 
    arr: self.state.concat([7]) 
}, 2000); 
1

你引用同一陣列中的if,即,要修改的同一陣列,而不是創建一個新的,你在shouldComponentUpdate工作的兩個引用同一個數組。

You should always treat props and state as immutable因此創建一個新的數組與.concat,而不是推入陣列狀態將解決您當前的問題。

setTimeout(function() { 
    this.setState({arr: this.state.concat([7])}); 
}.bind(this), 2000); 

如果你已經中shouldComponentUpdatethis.props.arr === nextProps.arr你會看到陣列將彼此相等。