为什么React的Contexts很好,但我们没有使用它?(外网博客)

Why React Contexts Are Great and Why We Didn’t Use Them

(还是翻译)

前言

Web 应用程序维护状态以实现更高级的用户交互,当我们将电子邮件输入网站时,我们希望该网站能够记住这个电子邮件,而不是在显示的时候一遍又一遍地重复输入它。

在 React 渲染中记住信息的一种方法是使用状态,特别是 useContext 钩子。我查看了 useContext 并开始在项目中使用它们,但最终改为了使用组件传参。这是我在这个过程中学到的。

什么是 React Contexts?

React Contexts 允许读取和写入状态对象,以任何形式存入 useContext 挂钩,并通过 provider 组件在任何组件层级结构中访问。状态可以是任何变量和函数的集合。

provider 是一个 React 组件,它设置初始状态并允许所有后代访问改状态。这种简单性使得 React Contexts 变得很灵活。

它还允许在 Web 应用程序中使用多个不同的Contexts,具体取决于应用程序中呈现的组件。你可以使用状态本身的一部分函数来修改 React Contexts 中的变量。

使用 React Contexts 的好处包括易于导入,并且能够将 useContext 挂钩添加到任何组件而不需要修改传参。

我们在哪发现的问题?

我们了解了useContext,并开始在我们的项目中使用它,以存储用户工作流中所有步骤的信息。我们添加了工作流所需的信息,并很快看到Contexts状态随着函数和变量增多而扩展。这本身并不是一个大问题。状态类型都在一个文件中,保持可读。

问题是,修改当前工作流变量不需要任何权限。当组件导入useContext时,它会获得完全的读写权限,工作流难以判断是否是意外操作导致变量修改的操作。在开发前的四周内,该状态发生了有趣的行为,我们可以单机一个按钮,这个更改将会通过多个步骤和组件进行传播。然而,即使小团队中每个人对组件库都很熟悉,这样也会使代码变得很难维护。

我们做了什么?

我们决定转移到一个状态对象,该对象从一个组件传递到另一个组件。好处是我们可以在每一层进行检查,以确保只给暴露给组件所需要的状态和功能。这有利于我们缩小每个组件的职责,提高代码可读性。

我们发现React Contexts支持简单数据共享。然而这个工具需要有规律地来有效控制Contexts中的内容。我们团队是否因为没有使用React Contexts而失去了机会?这是我们理解上的问题还是工具本身的问题?请在评论区告诉我,并且我们始终尝试为每个项目找到正确的模式。

留言

评论1

谢谢你的分享,使用全局Contexts听起来更像是一种反面模式(指的是在实践中明显出现但又低效或是有待优化的设计模式)。我发现有价值的是使用多个Contexts,每个Contexts都专注于某个域。这样组件将只获得所需要的东西。

评论2

在我看来,如果不使用 setter 函数,你反对的观点就站不住脚。

比较好的方案是只允许父组件去修改状态。

如果你只是希望某些不同的组件能设置状态, 你也可以将Contexts拆成状态和 setter Contexts。只要 setter 引用稳定,只更改状态的组件只需要访问后者,也不会由于状态更新而重新渲染。这样你可以通过查找 setter 而锁定到更改状态的子级。

这可能在某些项目中不起作用,但我觉得你重新引入了Contexts避免的东西:prop-drilling(在 React 中经常会碰到父组件一层一层地传参到子组件,这种行为叫做prop-drilling,drilling是下钻的意思)。

评论3

从我对你项目的有限理解来看,我不太确定你为什么选择在项目中用Contexts API。听起来你构建了很多用户表单,但没有人主张在本地组件或工作流中使用Contexts。你这样说是因为这在代码库中是不长久的。Contexts 不是用来替代状态的,它也不是用来替代像 redux 这种状态管理工具的,而是用来替代深层组件树,或者不相干的组件(无共同父级),以便轻松访问共同的状态值。

评论4

这根本不是Contexts的使用方式,官方文档会在你使用之前就告诉你这一点。不太清楚博客里是如何保证这一点的,因为“我们尝试了一个工具,却不知道的他是如何工作的,当我们不知道它是如何工作时,我们就放弃了它”。

评论5

Immense swag here ngl (不知道这个咋翻译)

评论6

所以你用 useContext 取代了 Props下钻……

我认为 Contexts 是行的,但不是直接以原生的方式使用,因为它会导致没必要的re-render,我们需要以冗余的方式包装它,这样我们就可以使用 memoization,因为 useContext 将在组件内使用,它不关心 useMemo

评论7

实际上,我找到了一种修改useReducer和createContext的方法,以便只为特定组件提供我想要读取的属性。

我注意到,一旦在具有全局状态的组件上使用Context,它将在每次更改状态中的一个项时重新读取。这是因为当你创建一个上下文时,它有一个键“Provider”,和键“Consumer”,你需要删除Consumer和Provider,并为它们放置自己的代码,以处理注册自己的监听器和何时更新,而不是React自己做这项工作。当reducer更新状态时,需要更改useReducer。您可以通过在回调认为必要时强制更新来实现这一点


个人总结

以为是技术分享,但实际上是针对React的Contexts使用上的讨论,这个也有使用过,但确实【评论6】的说法是现在项目插件中比较主流的,如开发中使用的useModel,是umi框架中的一个Hooks。(诸如其他的插件,我也还没去了解过,有缘再分享这种插件。)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容