上一個評論功能的案例中,可能會有些同窗會對一個地方感到疑惑: CommentList
中顯示的評論列表數據爲何要經過父組件 CommentApp
用 props
傳進來?爲何不直接存放在 CommentList
的 state
當中?例如這樣作也是能夠的:html
class CommentList extends Component { constructor () { this.state = { comments: [] } } addComment (comment) { this.state.comments.push(comment) this.setState({ comments: this.state.comments }) } render() { return ( <div> {this.state.comments.map((comment, i) => <Comment comment={comment} key={i} /> )} </div> ) } }
若是把這個 comments
放到 CommentList
當中,當有別的組件也依賴這個 comments
數據或者有別的組件會影響這個數據,那麼就帶來問題了。舉一個數據依賴的例子:例如,如今咱們有另一個和 CommentList
同級的 CommentList2
,也是須要顯示一樣的評論列表數據。函數
CommentList2
和 CommentList
並列爲 CommentApp
的子組件,它也須要依賴 comments
顯示評論列表。可是由於 comments
數據在 CommentList
中,它沒辦法訪問到。工具
遇到這種狀況,咱們將這種組件之間共享的狀態交給組件最近的公共父節點保管,而後經過 props
把狀態傳遞給子組件,這樣就能夠在組件之間共享數據了。this
在咱們的例子當中,若是把 comments
交給父組件 CommentApp
,那麼 CommentList
和 CommentList2
均可以經過 props
獲取到 comments
,React.js 把這種行爲叫作「狀態提高」。spa
可是這個 CommentList2
是咱們臨時加上去的,在實際案例當中並無涉及到這種組件之間依賴 comments
的狀況,爲何還須要把 comments
提高到 CommentApp
?那是由於有個組件會影響到 comments
,那就是 CommentInput
。CommentInput
產生的新的評論數據是會插入 comments
當中的,因此咱們遇到這種狀況也會把狀態提高到父組件。code
總結一下:當某個狀態被多個組件依賴或者影響的時候,就把該狀態提高到這些組件的最近公共父組件中去管理,用 props
傳遞數據或者函數來管理這種依賴或着影響的行爲。htm
咱們來看看狀態提高更多的例子,假設如今咱們的父組件 CommentApp
只是屬於更大的組件樹 PostApp
的一部分:blog
而這個更大的組件樹的另外的子樹的 CommentsCount
組件也須要依賴 comments
來顯示評論數,那咱們就只能把 comments
繼續提高到這些依賴組件的最近公共父組件 PostApp
當中。生命週期
如今繼續讓咱們的例子極端起來。假設如今 PostApp
只是另一個更大的父組件 Index
的子樹。而 Index
的某個子樹的有一個按鈕組件能夠一鍵清空全部 comments
(也就是說,這個按鈕組件能夠影響到這個數據),咱們只能繼續 commenets
提高到 Index
當中。get
你會發現這種無限制的提高不是一個好的解決方案。一旦發生了提高,你就須要修改原來保存這個狀態的組件的代碼,也要把整個數據傳遞路徑通過的組件都修改一遍,好讓數據可以一層層地傳遞下去。這樣對代碼的組織管理維護帶來很大的問題。到這裏你能夠抽象一下問題:
如何更好的管理這種被多個組件所依賴或影響的狀態?
你能夠看到 React.js 並無提供好的解決方案來管理這種組件之間的共享狀態。在實際項目當中狀態提高並非一個好的解決方案,因此咱們後續會引入 Redux 這樣的狀態管理工具來幫助咱們來管理這種共享狀態,可是在講解到 Redux 以前,咱們暫時採起狀態提高的方式來進行管理。
對於不會被多個組件依賴和影響的狀態(例如某種下拉菜單的展開和收起狀態),通常來講只須要保存在組件內部便可,不須要作提高或者特殊的管理。