上一个评论功能的案例中,可能会有些同窗会对一个地方感到疑惑: 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 以前,咱们暂时采起状态提高的方式来进行管理。
对于不会被多个组件依赖和影响的状态(例如某种下拉菜单的展开和收起状态),通常来讲只须要保存在组件内部便可,不须要作提高或者特殊的管理。