2016-01-15 27 views
1

這裏有一個簡單的例子:修改陣營輔元件道具渲染後

copyButton = <SomeReactComponent title="My Button" /> 

this.clipboard = new Clipboard('button#copy-button'); 
this.clipboard.on('success',() => { 
    this.copyButton.props.title = "Copied!"; 
}); 

render =() => { 
    return (
     ... 
     { this.copyButton } 
     ... 
    ); 
} 

使用Clipboard.js,按我的按鈕的時候,我有些文本複製到剪貼板。在成功的副本上,我想更改我的複製按鈕的標題以反映這一點。我保留引用的按鈕組件已經被渲染,並且this.copyButton.props.title顯然不起作用,因爲組件是不可變的。

那麼,我會如何改變我的按鈕上的title的值?我知道我可以在父組件中擁有一個狀態屬性,但我寧願避免讓父組件完成無狀態。我可以簡單地在成功回調中重新指定this.copyButton(我試過但沒有運氣)?

更一般地講,如果父母組件更新他們的孩子的道具應該如何?使用狀態真的是唯一的方法嗎?

注意:如果有問題,我正在使用ES6。

回答

1

考慮到您試圖更新按鈕文本的狀態,而不是以某種形式(在父組件或子組件中)使用反應狀態,可能會感覺有點不方便。但是,這是可能的。想到的最初方法是使用React.cloneElement創建copyButton的新版本,並使用title支持。然後使用this.forceUpdate用更新子組件重新渲染父組件。事情是這樣的:

this.clipboard.on('success',() => { 
    this.copyButton = React.cloneElement(this.copyButton, { 
     title: 'Copied!' 
    }); 
    this.forceUpdate(); 
}); 

https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement

話雖這麼說,在這種情況下使用state幾乎肯定會既爲可讀性和運行時更好(克隆元素和強制重新渲染是不便宜)。

+0

P.S.嗨布倫丹! – taylorc93

+0

是的,我只是在父組件中使用狀態。另外-_- – barndog

0

這對我來說並不是很反應。

我想你想要做這樣的事情:

getInitialState =() => { 
    return { 
    title: 'Button Title' 
    }; 
}; 

componentDidMount =() => { 
    this.clipboard = new Clipboard(this.refs.copyButton); 
    this.clipboard.on('success',() => { 
    this.setState({ 
     title: 'Copied!' 
    }) 
    }); 
}; 

componentWillUnmount =() => { 
    // You should destroy your clipboard and remove the listener 
    // when the component unmounts to prevent memory leaks 
    this.clipboard.destroy(); 
    // or whatever the comparable method is for clipboard.js 
}; 

render =() => { 
    return (
    ... 
    <SomeReactComponent ref="copyButton" title={this.state.title} /> 
    ... 
); 
}; 

最終的結果是,在最初的按鈕坐騎渲染。然後將其ref傳遞到componentDidMount(),它實例化剪貼板和success偵聽器。點擊按鈕後,它會調用this.setState()來更新按鈕組件的內部title狀態,該狀態會自動觸發組件的新標題重新呈現。

另外,根據React docs,如果可以的話,您想盡量避免使用forceUpdate()

通常情況下,您應該儘量避免使用forceUpdate(),只能從render.props和this.state中讀取render()。這使得你的組件「純粹」,你的應用程序變得更簡單,更高效。