为什么使用React上下文(Context)比只传递props对象更好?

huangapple go评论62阅读模式
英文:

Why is using React Context better than just passing around a props object?

问题

我一直在阅读关于在React中使用上下文的优势,但我并不信服。我想知道我是否遗漏了什么。

上下文提供了一种通过组件树传递数据的方式,而不必在每个级别手动传递props。

在主组件中创建一个props对象并在下属组件之间传递它有什么麻烦呢?类似于:

// 在顶层执行一次(我假设[foo,foo_set]和[bar,bar_set]是状态变量):
const props = { foo, foo_set, bar, bar_set, thisAndThat, theOther, whatever, etcAndEtc };

// 包括一个组件
<MyComponent1 {...props} />

// 包括另一个
<MyComponent2 {...props} />

(也许最好使用与props不同的名称来表示此对象,因为组件可能具有其他属性。无论如何。)

然后在MyComponent1中,您可以访问所有所需的props,或不访问它们。例如:

...
const MyComponent1 = (props) => {
...
// 在这里,我们可以使用任何需要的props,例如props.bar,props.bar_set,props.theOther
const localVar = props.bar * 2;
props.bar_set(localVar);
// 这将更改整个应用程序中bar的值
...
}

我认为上面的优势在于,您可以将props对象传递给其他子子组件,而不必担心是否有任何遗漏。

或者:

...
const MyComponent1 = ({ bar, bar_set, theOther }) => {
...
// 在这里,我们可以在相同的示例中使用bar,bar_set,theOther
const localVar = bar * 2;
bar_set(localVar);
...
}

此选项的优势在于语法更短。所以,我的观点是,为什么不只是使用标准的JavaScript语法?在有足够多的概念可以用来做各种其他事情的情况下,为什么要引入新的概念呢?

英文:

I've been reading about the advantages of using Context in React and I am unconvinced. I'm wondering if there's something I've missed.

> Context provides a way to pass data through the component tree without having to pass props down manually at every level.

What's the hassle in creating a props object in the main component and just passing it around among the underlings? Something like:

// do this once at top level (I&#39;m assuming [foo, foo_set] and [bar, bar_set] are state variables):
const props = {foo, foo_set, bar, bar_set, thisAndThat, theOther, whatever, etcAndEtc}

// including one component
&lt;MyComponent1 {...props } /&gt;

// including another
&lt;MyComponent2 {...props } /&gt;

(Maybe better to use another name than props for this object, as the components can have other properties. Anyway.)

Then in MyComponent1 you can access all the props you want, or not access them. Either:

...
const MyComponent1 = (props) =&gt; {
...
// here we can use any props we need, props.bar, props.bar_set, props.theOther for example
const localVar = props.bar * 2;
props.bar_set(localVar);
// this changes the value of bar throughout the app
...
}

the advantage of the above, as I see it, is that you can pass around the props object to other sub-sub-components and not worry about whether you have anything missing.
Or:

...
const MyComponent1 = ({bar, bar_set, theOther }) =&gt; {
...
// here we can use bar, bar_set, theOther in the same example
const localVar = bar * 2;
bar_set(localVar);
...
}

The advantage of this option being that the syntax is shorter.

So my point is why not just use the standard JavaScript syntax? Why introduce new concepts when there are plenty to assimilate to do all sorts of other things?

答案1

得分: 5

考虑到大多数应用程序的一个常见情况:你有认证信息(例如,当前用户),一个路由库(例如,react-router),和一个主题对象(用于确定使用哪些颜色)。这些信息分散在应用程序的各个组件中。

你想在组件树的底部某个地方渲染一个按钮。这个按钮将显示用户的头像,因此它需要认证数据。当点击时,它需要导航功能,因此它需要来自路由库的导航函数。而且,它需要根据主题自行设置样式。

当然可以通过props来实现,但是为了使按钮获取props,它上面的每个组件都必须获取并转发这些props。这可能会非常深入,例如页面组件 -> 区块组件 -> 表格 -> 行 -> 小部件 -> 按钮,而其中大多数组件并不需要这些信息,它们只是为了将props继续向下传递。

而且你可以轻松想象到,应用程序可能需要跨越3个以上的数据片段的情况。

> 麻烦在哪里

大多数人认为这种“prop drilling”很麻烦,但让我们假设你并不觉得麻烦。问题在于,它会影响性能。如果每个组件都必须接收应用程序可能需要的完整“全局”值集,那么任何时候有任何变化,整个应用程序都必须重新渲染。诸如react.memo之类的优化就会失去效果。如果你只传递你需要的props,性能会好得多。

英文:

Consider a fairly common case for most applications: You have authentication information (eg, the current user), a routing library (eg, react-router), and a theme object (what colors to use). These are needed in components scattered throughout the app.

You want to render a button somewhere down at the tip of the component tree. It's going to show the user's avatar, so it needs the authentication data. It's going to navigate when clicked, so it needs the navigate function from the routing library. And it needs to style itself according to the theme.

This certainly can be done through props, but in order for the button to get the props, every component in the chain above it must get and forward those props too. This could be many components deep, like page component -> section component -> table -> row -> widget -> button, and most of them don't need that information for themselves, so they're just taking the props in order to forward it along.

And you can easily imagine cases where there are more than 3 pieces of data that are needed across the app.

> What's the hassle

Most people find this "prop drilling" to be a hassle, but let's assume you don't. You still have the problem that it has bad performance. If every component must receive the full set of "global" values that the app might need, then any time anything changes, the entire app must rerender. Optimizations like react.memo become effectively useless. You will get much better performance if you only pass the props you need.

答案2

得分: 0

更容易编辑代码(无需删除未使用的变量,例如)
更好的可读性(您不会看到不必要的变量,您会看到哪个组件正在使用变量)
更少的性能浪费(防止使用不必要的变量)

假设您有10个子组件 - 您将不得不通过10个组件传递一个变量。
如果某些组件可以具有相同的变量名称怎么办?您将不得不在一段时间内编辑您传递的变量,然后稍后再编辑。

英文:

Easier to edit code (You don't have to delete for example unused variable)
Better redability (You dont see unnescesary variables, and You see which component is using variables)
Lesser performance waste (preventing from consuming unnescesarry variables)

Suppose You got 10 descendants in - You would have to pass one variable through 10 of components.
What if some could have the same variable name ? You would have to edit Your passed variable for a while, then edit back later.

答案3

得分: 0

总结一下:

  • 使用上下文比将所有内容塞入单个对象变量更高效,因为它避免了在任何内容变化时重新渲染整个应用程序。
  • 人们认为传递单个变量比引入特定语法更麻烦。
  • 上下文还允许您在应用程序的不同部分为相同的变量具有不同的值。这在这里得到了展示(在我看来是最好的解释):https://beta.reactjs.org/learn/passing-data-deeply-with-context
  • 上述文章还指出,有时传递props是最佳解决方案。它列出了上下文的用例列表,并介绍了每种情况下提供的优势。
英文:

To sum up:

  • Using Context more efficient than stuffing everything into a single object variable, because it avoids re-rendering the whole app when anything changes.
  • People think passing a single variable around is more hassle than introducing specific syntax.
  • Context also allows you to have different values for the same variable in different parts of the app. This is shown here (the best explanation IMHO) : https://beta.reactjs.org/learn/passing-data-deeply-with-context
  • The above article also specifies that sometimes passing props is the best solution. It gives a list of use cases for context, and the advantages provided in each case.

huangapple
  • 本文由 发表于 2023年2月17日 23:56:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75486540.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定