【问题标题】:React - Fetch data in the parent or inside its childs?React - 在父级或子级中获取数据?
【发布时间】:2021-11-12 10:23:56
【问题描述】:

注意:我没有使用 Redux(仅 Context + Hooks)

简介

我有一个屏幕“Profile”,它呈现一个TabView

这个TabView,将两个组件渲染为场景:

  1. 用户帖子
  2. 用户信息

我的个人资料屏幕,从我的数据库中获取用户数据,因为它必须呈现一些依赖于这些数据的内容。

此外,它通过 props 传递给我的“UserInformation”组件,因为它只是呈现用户数据。所以...我的“UserInformation”组件中没有数据获取。

另一方面,我的“UserPosts”组件负责获取用户帖子,因为它呈现了一个组件“UserPostsGrid”,该组件使用分页呈现这些帖子(无尽的平面列表)。

注意:数据获取是在自定义钩子中执行的,而不是直接在内部 组件(此外,这些钩子管理相应的有状态 数据)。

问题

当用户在“Profile 中拉动刷新”时,我需要刷新 用户数据用户帖子 时出现主要问题强>”屏幕。

此屏幕获取用户数据没有问题,正如我之前所说的“个人资料”屏幕负责该操作。

但是帖子是我孩子的状态数据...

多种解决方案?

我曾想过使用当前的解决方案来解决这个问题:

React.forwardRef() + React.useImperativeHandle()

有了这个,我将能够将 ref 传递给我的“UserPosts”并使用命令式编程来访问数据获取方法:userPostsRef.current.refreshPosts();

我从未见过像这样解决此问题的其他方案,但它应该可以工作。相反,其他编码人员实现了一个 ContextProvider 来处理所有数据并能够在他们想要的任何地方访问它。我在这里注意到的主要问题是:额外的记忆 + 额外的重新渲染。

另一种解决方案可能是在父级内部实现所有数据获取,并通过道具将相应的回调传递给子级。我在这里注意到的主要问题是我们正在创建某种“上帝组件”并且我们可能有多行代码......

我的问题

实施第一个解决方案是反模式还是不好的做法

【问题讨论】:

  • 是的,它是一个反模式,因为现在组件依赖于它不应该知道的父级。在父组件中使用 context/redux 或将回调作为 prop 和控制数据传递。这就是它的本意。
  • As always, imperative code using refs should be avoided in most cases. 我想说这就是其中一种情况。
  • @CodeSpirit 我认为子组件根本不依赖于父组件。我的意思是,依赖孩子的是父母。如果您只是在不传递 ref 的情况下渲染孩子,您将无法使用其“刷新”方法,该方法应该与 pull-to-refresh 一起使用(可能在父组件中)。子组件本身将能够执行其各自的功能(不依赖于拉动刷新的功能)。
  • @kasav 顺便说一句,如果我将获取父组件的逻辑或状态管理分别与上下文提供者分离,则子级将依赖于父级(问题?)或该上下文(这没问题)。至少,这是我的想法。我的意思是,如果我将孩子的逻辑移到父母身上,将不会有可重用性。
  • 在这种特殊情况下,我不知道为什么它是一种反模式,它使组件比使用“回调作为道具”解决方案。如果我想将该组件移动到另一个屏幕以便在没有当前父级的情况下呈现它怎么办?

标签: javascript reactjs react-native react-redux react-hooks


【解决方案1】:

回答您的问题:

是的,is an antipattern in React,因为 React 是围绕着你指定应用程序状态的想法构建的,然后让 React 根据给定的状态渲染组件。

如果有什么事情发生了变化,你应该指定一个新的状态来表示与旧状态的不同。

只有在没有其他选择的情况下才应该使用参考。基本上,如果你使用 Refs,你会说“我不想在我的代码的这个特定部分使用 React”。

与往常一样,在大多数情况下应避免使用 refs 的命令式代码

使用状态代替命令:

我会通过尝试命令性行动转化为某种信息状态来解决这类问题。

  • 用户说“get me the latest data”,这是一个命令,即命令
  • 现在我会问“用户现在告诉我的数据状态是什么?”
  • 答案是“此数据不再是最新的”,这可以表示为一种状态,并通过 props 传递。

解决您的问题:

例如你可以使用一个属性needsUpdate,当数据应该更新时设置为true,当获取数据时设置为false

为了避免不必要的渲染(设置needsUpdate = false 会导致另一个调用,例如useEffect,即使那里什么也没发生),我可能会使用像latestUpdateRequest 这样的子组件道具和像latestUpdate 这样的子状态,它包含一个计数器或时间戳,然后比较if(latestUpdateRequest > latestUpdate)

要通知父级更改,只需将dataUpdated() 之类的回调函数作为道具传递。

【讨论】:

  • 但是,父母怎么知道孩子已经完成了任务呢?我的意思是,这只是一个下拉刷新,看看 instagram 用户配置文件屏幕。当用户刷新时,用户帖子也会重新计算。
  • 只需传递一个像dataHasUpdated() 这样的回调函数作为道具。我也更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 2020-06-20
  • 2018-03-09
  • 1970-01-01
  • 2021-06-11
  • 2021-07-19
  • 2017-12-08
  • 1970-01-01
相关资源
最近更新 更多