React.js 小书 Lesson17 - 前端应用状态管理 —— 状态提升
- 作者:胡子大哈
- 原文链接:http://huziketang.com/books/react/lesson17
- 转载请注明出处,保留原文链接和作者信息。
上一个评论功能的案例中,可能会有些同学会对一个地方感到疑惑: CommentList
中显示的评论列表数据为什么要通过父组件 CommentApp
用 props
传进来?为什么不直接存放在 CommentList
的 state
当中?例如这样做也是可以的:
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
把状态传递给子组件,这样就可以在组件之间共享数据了。
在我们的例子当中,如果把 comments
交给父组件 CommentApp
,那么 CommentList
和 CommentList2
都可以通过 props
获取到 comments
,React.js 把这种行为叫做“状态提升”。
但是这个 CommentList2
是我们临时加上去的,在实际案例当中并没有涉及到这种组件之间依赖 comments
的情况,为什么还需要把 comments
提升到 CommentApp
?那是因为有个组件会影响到 comments
,那就是 CommentInput
。CommentInput
产生的新的评论数据是会插入 comments
当中的,所以我们遇到这种情况也会把状态提升到父组件。
总结一下:当某个状态被多个组件依赖或者影响的时候,就把该状态提升到这些组件的最近公共父组件中去管理,用 props
传递数据或者函数来管理这种依赖或着影响的行为。
我们来看看状态提升更多的例子,假设现在我们的父组件 CommentApp
只是属于更大的组件树 PostApp
的一部分:
而这个更大的组件树的另外的子树的 CommentsCount
组件也需要依赖 comments
来显示评论数,那我们就只能把 comments
继续提升到这些依赖组件的最近公共父组件 PostApp
当中。
现在继续让我们的例子极端起来。假设现在 PostApp
只是另外一个更大的父组件 Index
的子树。而 Index
的某个子树的有一个按钮组件可以一键清空所有 comments
(也就是说,这个按钮组件可以影响到这个数据),我们只能继续 commenets
提升到 Index
当中。
你会发现这种无限制的提升不是一个好的解决方案。一旦发生了提升,你就需要修改原来保存这个状态的组件的代码,也要把整个数据传递路径经过的组件都修改一遍,好让数据能够一层层地传递下去。这样对代码的组织管理维护带来很大的问题。到这里你可以抽象一下问题:
如何更好的管理这种被多个组件所依赖或影响的状态?
你可以看到 React.js 并没有提供好的解决方案来管理这种组件之间的共享状态。在实际项目当中状态提升并不是一个好的解决方案,所以我们后续会引入 Redux 这样的状态管理工具来帮助我们来管理这种共享状态,但是在讲解到 Redux 之前,我们暂时采取状态提升的方式来进行管理。
对于不会被多个组件依赖和影响的状态(例如某种下拉菜单的展开和收起状态),一般来说只需要保存在组件内部即可,不需要做提升或者特殊的管理。
课后练习
因为第三方评论工具有问题,对本章节有任何疑问的朋友可以移步到 React.js 小书的论坛 发帖,我会回答大家的疑问。
React.js 小书 Lesson17 - 前端应用状态管理 —— 状态提升的更多相关文章
- React.js 小书 Lesson2 - 前端组件化(一):从一个简单的例子讲起
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson2 转载请注明出处,保留原文链接和作者信息. 很多课程一上来就给大家如何配置环境.怎么写 Re ...
- React.js 小书 Lesson3 - 前端组件化(二):优化 DOM 操作
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson3 转载请注明出处,保留原文链接和作者信息. 看看上一节我们的代码,仔细留意一下 change ...
- React.js 小书 Lesson4 - 前端组件化(三):抽象出公共组件类
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson4 转载请注明出处,保留原文链接和作者信息. 为了让代码更灵活,可以写更多的组件,我们把这种模 ...
- 【React.js小书】动手实现 React-redux(五):Provider - 方志
我们要把 context 相关的代码从所有业务组件中清除出去,现在的代码里面还有一个地方是被污染的.那就是 src/index.js 里面的 Index: 1234567891011121314151 ...
- React.js 小书介绍
React.js 小书 Github 关于作者 这是一本关于 React.js 的小书. 因为工作中一直在使用 React.js,也一直以来想总结一下自己关于 React.js 的一些知识.经验.于是 ...
- React.js小书总结
(迁移自旧博客2017 08 27) 第一阶段 react的组件相当于MVC里面的View. react.js 将帮助我们将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合.嵌套,就成 ...
- React.js 小书 Lesson16 - 实战分析:评论功能(三)
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson16 转载请注明出处,保留原文链接和作者信息. 接下来的代码比较顺理成章了.修改 Commen ...
- React.js 小书 Lesson12 - state vs props
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson12 转载请注明出处,保留原文链接和作者信息. 我们来一个关于 state 和 props 的 ...
- React.js 小书 Lesson5 - React.js 基本环境安装
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson5 转载请注明出处,保留原文链接和作者信息. 安装 React.js React.js 单独使 ...
随机推荐
- c#递归理解
什么是递归函数? 任何一个方法既可以调用其他方法又可以调用自己,而当这个方法调用自己时,我们就叫它递归函数或者递归方法! 说白了,就是调用自己. 通常递归有两个特点: 1.递归方法一直会调用自 ...
- HTTP总结
参考: https://www.cnblogs.com/fuqiang88/p/5956363.html https://www.cnblogs.com/zlingh/p/5887143.html h ...
- Setting property 'source' to 'org.eclipse.jst.jee.server:web' did not find a matching property原因
这个问题困扰了好久,虽然只是tomcat的一个警告,但强迫症让我总觉得不舒服,搜索了好多文章才找到知乎上一篇处理的最好的.另外:能找谷哥,尽量不要度娘,太浪费时间. 具体操作如下: 默认情况下,ser ...
- CHOCBase
1.基础常用知识点 1.1 监听某个对象变化的四种方式 代理监听Delegate Notification通知 KVO键值监听 Block代码块 addTarget方法 1.2 音频视频相册等 2.常 ...
- Educational Codeforces Round 62 (Rated for Div. 2)E(染色DP,构造,思维,组合数学)
#include<bits/stdc++.h>using namespace std;const long long mod=998244353;long long f[200007][2 ...
- django中itsdangerous的用法
itsdangerous用来解决什么问题,为什么需要用到itsdangerous? 安装命令:pip install itsdangerous 有时候你想向不可信的环境发送一些数据,但如何安全完成这个 ...
- luoguP2664 树上游戏
https://www.luogu.org/problemnew/show/P2664 考虑对于每种颜色包含的点和这些点的子节点建出虚树,发现只要将一个联通块中的东西 Dp + 差分一下就行了 当然要 ...
- dubbo源码分析--dubbo spi解析
1. 什么叫SPI? 简单总结就是一种使用类名字符串来动态实例化java类的方式,也就是反射. 2. java SPI与Dubbo SPI有什么区别 (此图来自网上,我没有刻意去截图) 然后在这个文件 ...
- 开发环境,eclipse编辑器java代码自动提示
Eclipse+ADT+Android SDK 搭建安卓开发环境 eclipse编辑器java代码自动提示 window-->Preferences-->JAva-->Content ...
- C++_友元1-友元类是什么
友元函数:不是类的成员函数,但是能够访问类的私有数据成员. 之前有个矛盾就是规定非成员函数不能直接访问类的私有数据,但是这会儿却可以,但那只是针对常规非成员函数而言,特殊的非成员函数就可以访问类的私有 ...