博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React.js 小书 Lesson17 - 前端应用状态管理 —— 状态提升
阅读量:5882 次
发布时间:2019-06-19

本文共 1968 字,大约阅读时间需要 6 分钟。


React.js 小书 Lesson17 - 前端应用状态管理 —— 状态提升

本文作者:

本文原文:

转载请注明出处,保留原文链接以及作者信息

在线阅读:


上一个评论功能的案例中,可能会有些同学会对一个地方感到疑惑: CommentList 中显示的评论列表数据为什么要通过父组件 CommentAppprops 传进来?为什么不直接存放在 CommentListstate 当中?例如这样做也是可以的:

class CommentList extends Component {  constructor () {    this.state = { comments: [] }  }  addComment (comment) {    this.state.comments.push(comment)    this.setState({      comments: this.state.comments    })  }  render() {    return (      
{this.state.comments.map((comment, i) =>
)}
) }}

如果把这个 comments 放到 CommentList 当中,当有别的组件也依赖这个 comments 数据或者有别的组件会影响这个数据,那么就带来问题了。举一个数据依赖的例子:例如,现在我们有另外一个和 CommentList 同级的 CommentList2 ,也是需要显示同样的评论列表数据。

示例图片

CommentList2CommentList 并列为 CommentApp 的子组件,它也需要依赖 comments 显示评论列表。但是因为 comments 数据在 CommentList 中,它没办法访问到。

遇到这种情况,我们将这种组件之间共享的状态交给组件最近的公共父节点保管,然后通过 props 把状态传递给子组件,这样就可以在组件之间共享数据了。

示例图片

在我们的例子当中,如果把 comments 交给父组件 CommentApp ,那么 CommentListCommentList2 都可以通过 props 获取到 comments,React.js 把这种行为叫做“状态提升”。

但是这个 CommentList2 是我们临时加上去的,在实际案例当中并没有涉及到这种组件之间依赖 comments 的情况,为什么还需要把 comments 提升到 CommentApp?那是因为有个组件会影响到 comments ,那就是 CommentInputCommentInput 产生的新的评论数据是会插入 comments 当中的,所以我们遇到这种情况也会把状态提升到父组件。

总结一下:当某个状态被多个组件依赖或者影响的时候,就把该状态提升到这些组件的最近公共父组件中去管理,用 props 传递数据或者函数来管理这种依赖或着影响的行为。

我们来看看状态提升更多的例子,假设现在我们的父组件 CommentApp 只是属于更大的组件树 PostApp 的一部分:

示例图片

而这个更大的组件树的另外的子树的 CommentsCount 组件也需要依赖 comments 来显示评论数,那我们就只能把 comments 继续提升到这些依赖组件的最近公共父组件 PostApp 当中。

现在继续让我们的例子极端起来。假设现在 PostApp 只是另外一个更大的父组件 Index 的子树。而 Index 的某个子树的有一个按钮组件可以一键清空所有 comments(也就是说,这个按钮组件可以影响到这个数据),我们只能继续 commenets 提升到 Index 当中。

你会发现这种无限制的提升不是一个好的解决方案。一旦发生了提升,你就需要修改原来保存这个状态的组件的代码,也要把整个数据传递路径经过的组件都修改一遍,好让数据能够一层层地传递下去。这样对代码的组织管理维护带来很大的问题。到这里你可以抽象一下问题:

如何更好的管理这种被多个组件所依赖或影响的状态?

你可以看到 React.js 并没有提供好的解决方案来管理这种组件之间的共享状态。在实际项目当中状态提升并不是一个好的解决方案,所以我们后续会引入 Redux 这样的状态管理工具来帮助我们来管理这种共享状态,但是在讲解到 Redux 之前,我们暂时采取状态提升的方式来进行管理。

对于不会被多个组件依赖和影响的状态(例如某种下拉菜单的展开和收起状态),一般来说只需要保存在组件内部即可,不需要做提升或者特殊的管理。

下一节中我们将介绍。

你可能感兴趣的文章
快速部署OpenShift应用
查看>>
fstab gpt screen
查看>>
如何给Apache Pig自定义UDF函数?
查看>>
IDE、SATA、SCSI、SAS、FC、SSD 硬盘类型
查看>>
HTML模块通信
查看>>
mysql登陆启动报错 ERROR 2002 (HY000) 解决方法
查看>>
LINUX小实验
查看>>
Linux服务器---流量监控webalizer
查看>>
常见Mysql系统参数调整
查看>>
我的友情链接
查看>>
2012年度十大杰出IT博客之 罗升阳
查看>>
慧眼识人?做“博”乐?投票贡献拿大奖!
查看>>
python学习笔记一 介绍、基本语法、流程控制
查看>>
【翻译】Ext JS最新技巧——2016-3-4
查看>>
socket收发超时
查看>>
我的友情链接
查看>>
AHCI和IDE的区别,如何在AHCI模式下安装系统
查看>>
实测 Mysql UUID 性能
查看>>
Linux系统启动流程
查看>>
字体颜色的脚本
查看>>