【问题标题】:Data flow in React app w/ functional components & hooks带有功能组件和钩子的 React 应用程序中的数据流
【发布时间】:2021-03-16 05:00:09
【问题描述】:

我正试图在一个带有功能组件和钩子的 React 应用程序中围绕数据流展开思考。

我想知道:

  1. 当数据更改(状态更改)导致执行级联代码时...什么代码(例如,在每个组件中运行和不运行...显然存在选择性,例如“不要放那个如果您不希望 那个 代码运行,则在 deps 数组中的变量")?
  2. 在这样的数据级联过程中,家庭树的“家庭”部分是如何确定的?数据会传递给兄弟姐妹吗?它是否只传给子代(如果传递了用于更新父代的函数,则传给父代)?

为了澄清我的想法,我在每个文件名的结尾都使用了这样的标签约定:我声称(并要求更正!)1 是 2 的父级; 2 是 3a 的父级(我认为……自定义挂钩可以是“子级”吗?)、3b 和 3c;而 3c 是 4c 的父级。

显然,父/子数据流是 React 的自然组成部分。兄弟姐妹之间呢?那是问题发生的地方吗?当然,在给定文件中“传递数据”可能是危险的(相对于控制是否以及何时渲染一段数据),显然解决方案是将数据“提升”到树上。但即便如此……如果不清楚数据如何回落……以及我们应该寻找什么问题,那么将数据提升一个(或更多)水平是没有意义的。

index1.tsx

...
<App/>
...

App2.tsx

...
const App = () => {
  ...
  const {varFromCustomHook} = useAppLogic(varToCustomHook);
  ...
  <FooComponent varToFoo={varToFoo} functToFoo={functToFoo}/>;
  <BarComponent/>;
  ...
};
...

useAppLogic3a.tsx

...
interface Props {
  varToCustomHook;
};
const useAppLogic (props: Props) {
...
  return {varFromCustomHook};
};

FooComponent3b.tsx

...
interface Props {
  varToFoo;
  functToFoo;
}
const FooComponent = (props: Props) => {
  ...
  funcToFoo(importantData);
  ...
  <div>{varToFoo}</div>;
  ...
};

BarComponent3c.tsx

...
const BarComponent = () => {
  ...
  <FoobarComponent/>;
  ...
};

FoobarComponent4c.tsx

...
const FoobarComponent = () => {
  ...
};

【问题讨论】:

    标签: reactjs react-hooks state react-functional-component


    【解决方案1】:

    一个react组件就是一个react组件,不管是基于类的组件还是函数式组件都是一个实现细节。数据以 props 的形式向下流向反应树,从父级到子级。这是 React 中的普遍真理。

    当数据变化(状态变化)导致代码级联 执行...什么代码(例如,在每个组件中,运行和不运行...... 显然存在选择性,例如“不要将该变量放入 如果您不想运行该代码,请使用 deps 数组")?

    当状态和/或道具更新时,功能组件被重新渲染。功能组件的整个函数体技术上是“渲染”函数,因此所有在组件渲染时运行。 p>

    您专门询问钩子。每个渲染周期都会执行钩子,按照它们声明的顺序执行,如果存在依赖数组,则对其进行评估,如果 any 依赖未能通过浅层引用相等性检查,则触发钩子的回调。

    在这样的过程中,家谱中的“家庭”部分是如何确定的? 数据级联?数据会传递给兄弟姐妹吗?是不是只给孩子 (或者如果传递了一个函数来更新父级,则为父级)?

    React 树的确定方式与几乎总是相同的方式确定,一个根节点和子节点,其中每个子组件都可以有更多的子节点。数据仍然只从父级传递给子级。回调仍然作为 props 传递(通常)以供子组件调用。

    评论问题

    useAppLogic 是否被视为 [在这种情况下为 App 的子级],还是可以自定义 钩子不被视为儿童(无论出于何种原因)?假设 答案是肯定的,那么无法使用AppLogic 返回一个得到的值 传递给它的兄弟 FooComponent?如果是,这不是数据吗 “水平”流动而不是向下流动?我不知道答案……但它 似乎这种数据传递是可能的(也许是 反模式,我不知道)。

    不,useAppLogic 是一个反应钩子,不能是任何东西的孩子,它是一个函数。只有 React 组件、HTML 元素和原语(字符串、数字等)可以是子元素,呈现为 JSX。数据只会向下流动。如果需要将数据传递给兄弟姐妹,则至少需要将其提升到最近的共同祖先。如果useAppLogicApp 中,并且FooComponent 是App 的子级,则挂钩返回的任何值都可以作为prop 传递给FooComponent

    如果(在上述情况下,我们已经在这些 cmets 中讨论过)怎么办 应用程序和应用程序的孩子 FooComponent 都使用了 useAppLogic?将 这是反模式吗?这显然允许父母和 孩子有一块没有“传递”的数据。 (出去 在肢体上……这是进入全球对话的窗口吗? 数据/useReducer?)。也许 cmets 中的这些要点会有所帮助 一些人,如果他们在答案中。

    React 钩子都是它们自己的实例。他们不共享任何状态,或与此相关的任何其他内容。没有足够的上下文来说明使用相同反应钩子的父组件和子组件是否是反模式,但我倾向于说不,不是,因为任何功能组件都可以使用任何反应钩子几乎出于任何原因。不是任何全局数据的窗口(useContext 钩子会尽可能接近一些“全局”数据)。

    【讨论】:

    • 太好了,谢谢!我可以就一些仍然困扰我的事情问几个问题吗? useAppLogic 是否被视为 [在这种情况下为 App 的子项],或者自定义挂钩是否可以不被视为子项(无论出于何种原因)?假设答案是肯定的,那么 useAppLogic 不能返回一个传递给它的兄弟姐妹 FooComponent 的值吗?如果是的话,这不是数据“水平”流动而不是向下流动吗?我不知道答案......但似乎这种数据传递是可能的(也许它是一种反模式,我不知道)。
    • @tarstevs 不,useAppLogic 是一个反应钩子,不能是任何东西的孩子,它是一个函数。只有 react 组件、HTML 元素和原语(字符串、数字等)可以是子元素,呈现为 JSX。数据只会向下流动。如果需要将数据传递给兄弟姐妹,则需要将其提升到至少最近的共同祖先。如果useAppLogicApp 中,并且FooComponentApp 的子级,则挂钩返回的任何值都可以作为prop 传递给FooComponent
    • 好吧,酷。我只能再想到一件事,然后我们将涵盖至少我能想到的所有基础(与数据流相关):如果(在上述情况下,我们已经在这些 cmets 中讨论过)useAppLogic 被使用App 和 App 的孩子 FooComponent?这会是反模式吗?这显然会允许父母和孩子拥有一段未被“传递”的数据。 (冒险出去......这一点是关于全局变量对话的窗口吗?)。如果他们在答案中,那么 cmets 中的这些点可能会对某些人有所帮助。
    • @tarstevs 当然。将 cmets 中问题的进一步答案移至根答案。
    猜你喜欢
    • 1970-01-01
    • 2020-02-13
    • 2019-12-08
    • 1970-01-01
    • 2019-12-22
    • 2020-07-29
    • 2020-05-13
    • 2016-06-29
    • 1970-01-01
    相关资源
    最近更新 更多