REECT:返回JSX和函数组件的函数之间的差异是什么?
function renderSomething(foo) {
return <div>sth {foo}</div>
}
function Something({ foo }) {
return <div>sth {foo}</div>
}
function Component(props) {
const { foo } = props
return (
<>
{renderSomething(foo)}
<Something foo={foo} />
</>
)
}
renderSomething()
和
的 JSX 结果是相同的。我想知道这两种方式之间有什么区别(例如渲染方式、行为、影响等)?
render方法(即renderSomething()
)适用于什么场景?我可以在里面使用挂钩吗?
function renderSomething(foo) {
return <div>sth {foo}</div>
}
function Something({ foo }) {
return <div>sth {foo}</div>
}
function Component(props) {
const { foo } = props
return (
<>
{renderSomething(foo)}
<Something foo={foo} />
</>
)
}
The JSX result of renderSomething()
and <Something />
is identical. I wonder what's the difference(e.g. render way, behavior, influence, etc) between these two ways?
And what applicable scenario for render method(i.e. renderSomething()
)? Can I use hooks inside?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
renderSomething(foo)
和
做完全不同的事情,但在特定用法中,最终结果是相同的:React 创建一个 React 元素,告诉它稍后渲染一个div
(如果使用该元素)。执行 renderSomething(foo) 是将renderSomething
视为一个钩子,这会影响您在运行时如何使用它。这里有两个主要区别:
使用
renderSomething(foo)
,您的代码会立即调用函数并传入参数。对于
,您并不是在调用Something
。您要求 React 记住它,并在以后需要渲染您执行这些调用的组件时调用它。因为调用
renderSomething
的是您的代码,而不是 React,所以如果您在其中使用了钩子,它们会将信息放入调用组件的实例和状态信息中。相反,如果Something
使用挂钩,则该实例和状态信息将存储在Something
本身的组件实例中。(还有其他差异。您不能通过
使用renderSomething
作为组件,因为函数组件名称必须以大写字母开头以将它们与 HTML 元素区分开来,并且因为renderSomething
需要一个字符串参数,而不是 props 对象。)让我们更仔细地看看其中的几个差异:
请注意,代码调用
renderSomething
(您会看到它的console.log
出现),但没有调用Something
(您看不到它的console.log
)。这是因为上面的差异#1。关键是组件的函数只有在需要渲染时才会被调用。我们没有渲染上面的任何结果,因此该函数永远不会被调用。第二个区别更微妙,但让我们假设两件事:
示例
)可能需要也可能不需要渲染它。这与
Something
配合得很好:但现在让我们用
renderSomething
尝试一下:当您勾选带有此错误的框时,它会爆炸:
这是因为当我们没有在第一次渲染时调用
renderSomething
时,这会使代码调用它。这是因为上面的#2:由于renderSomething
不是一个组件函数,它不会获得自己的组件实例,并且对其中的钩子的任何调用就像对父组件中的钩子的调用一样(示例
)。但函数组件有时不允许调用钩子,有时则不允许。这是因为 React 依赖于调用 hooks 的顺序,并且该顺序使其执行钩子管理时保持一致。同样,使用 renderSomething 就是使用 renderSomething 作为钩子(这正是自定义钩子的工作原理,最终调用内置钩子,然后将信息存储在父实例)。正如您所看到的,虽然您在示例中得到的结果是相同的,但总的来说它们是完全不同的东西。 :-)
renderSomething(foo)
and<Something foo={foo} />
do quite different things, but in that specific usage, the end result is the same: React creates a React element that tells it to render adiv
later (if the element is used). DoingrenderSomething(foo)
is treatingrenderSomething
like a hook, which has implications for how you use it when when it runs.Here are two key differences:
With
renderSomething(foo)
, your code is calling the function immediately and passing in the argument. With<Something foo={foo} />
, you aren't callingSomething
. You're asking React to remember it and call it later if/when it needs to render the component where you did these calls.Because your code, not React, calls
renderSomething
, if you used hooks in it, they'd be putting information in the calling component's instance and state information. In contrast, ifSomething
uses hooks, that instance and state information is stored in a component instance forSomething
itself.(There are other differences. You can't use
renderSomething
as a component via<renderSomething foo={foo} />
because function component names must start with upper case to differentiate them from HTML elements, and becauserenderSomething
expects a string argument, not a props object.)Let's look at a couple of those differences more closely:
Notice that the code called
renderSomething
(you see itsconsole.log
occur), but didn't callSomething
(you don't see itsconsole.log
). That's because of difference #1 above. The key thing is that a component's function is called only if it needs to be rendered. We haven't rendered either result above, so the function is never called.The second difference is more subtle, but let's suppose two things:
Example
) may or may not need to render it.That works just fine with
Something
:But now let's try it with
renderSomething
:It blows up when you tick the box with this error:
That's because that makes the code call
renderSomething
when we didn't call it on the first render. That's because of #2 above: SincerenderSomething
isn't a component function, it doesn't get its own component instance, and any calls to hooks within it are just like calls to hooks in the parent component (Example
). But function components aren't allowed to call hooks sometimes and not other times. That's because React relies on the order in which hooks are called, and that order has to be consistent for it to do its hook management. Again, usingrenderSomething
like that is usingrenderSomething
as a hook (this is exactly how custom hooks work, by ending up calling built-in hooks, which then store the information in the parent instance).So as you can see, while the result you got in your example was the same, in general they're quite different things. :-)