2015-12-07 25 views
1

爲了性能的緣故,我試圖在一些組件上實現shouldComponentUpdate。我們以通常的方式來做 - 有一個不可改變的模型並做參考比較。它的作用大部分,但我一直想知道如果我正確地處理道具的功能。Reactjs shouldComponentUpdate與函數

本質上,我的問題是:在shouldComponentUpdate中,通常在道具中使用函數做什麼?你忽略他們altoghether,或者你試圖比較它們嗎?

下面是一個例子:

var Inner = React.createClass({ 
    shouldComponentUpdate(newProps){ 
     return ??? 
    }, 

    render(){ 
     return <div onClick={this.props.onClick} />; 
    } 
}); 

var Outer = React.createClass({ 
    getInitialState(){ return {value: 0}; }, 

    render(){ 
     var val = this.state.value; 
     return <div> 
        <span>{val}</span> 
        <Inner onClick={() => { this.setState({value: val + 1}) }} /> 
       </div> 
    } 
}); 

假設我需要內部成分有shouldComponentUpdate(假設它呈現了很多次,這是很難渲染)。你將如何實現它?我嘗試了以下方法:

1)this.props.onClick === newProps.onClick - 如果您繼續傳遞相同的方法,但它在此示例中不起作用,因爲該方法是內聯創建的。

2)this.props.onClick.toString()=== newProps.onClick.toString() - 如果函數在閉包中沒有任何陳舊的東西 - 這不起作用,因爲val是在函數的關閉。 3)正如Michael所指出的,你可以忽略shouldComponentUpdate中的函數,其問題與2)一樣。

所有這些方法都可以引入細微的錯誤,是否有更簡單的方法呢?我知道很容易重寫這個例子來工作,但理想情況下,我希望能夠將shouldComponentUpdate行爲提取到儘可能健壯的mixin中,而不是將自身應用於這些問題。

回答

1

我不相信這是真的以往任何時候都需要跳過功能,在您的shouldComponentUpdate,但承認,它有時是不可避免的。

首先,雖然關於你的第一點內聯方法。當涉及到安全高效地重新渲染組件時,這總是會讓你很難,所以我建議儘可能使用內聯方法。你舉的例子可以實現這樣寫於是同樣的事情:

class Inner extends React.PureComponent { 
    // PureComponent performs the shallow equal check 
    render(){ 
    return <div onClick={this.props.onClick} />; 
    } 
}; 

class Outer extends React.Component { 

    constructor(props) { 
    this.state = { value: 0 }; 
    } 

    increment =() => { 
    this.setState({ value: this.state.value + 1 }); 
    } 

    render() { 
    return (<div> 
     <span>{val}</span> 
     <Inner onClick={this.increment} /> 
    </div>); 
    } 
}; 

如果你已經用完這個選項,它只是看起來並不像會爲你有,那麼你可以在自定義肯定寫用例工作shouldComponentUpdate跳過你的功能,我認爲這將是最好的解決方案。只要確保每次都沒有令人討厭的驚喜;如果你的函數在組件生命週期中有依賴關係發生變化,那麼重新考慮你的方法,或者將這些依賴關係作爲常規的props(它將觸發更新)向下傳遞,如果它們還沒有的話。

這是您可以使用的helpful package(儘管我還沒有嘗試過)。祝你好運!

+0

謝謝你的見解。我一定會停止使用道具的內聯函數。 – Michael

0

快速的想法是遍歷所有的鍵,然後typeOf是一個函數,然後不檢查,如果沒有 - >然後檢查。我懷疑第一級有很多兒童道具,所以不應該太慢。

而且說不定強調比較對象http://underscorejs.org/#isEqual會的工作,雖然,我沒有檢查

+0

所以你說我應該忽略shouldComponentUpdate中的函數。這與2)中的例子具有相同的缺點 - 下一次渲染Outer時,內部不會被重新渲染,因此單擊div不會增加計數器(函數閉包中的'val'仍然是相同的)。 –