首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与“常规Javascript函数”相比,“”的区别到底是什么?

与“常规Javascript函数”相比,“”的区别到底是什么?
EN

Stack Overflow用户
提问于 2022-09-01 17:46:56
回答 2查看 72关注 0票数 1

react大胆地指出,钩子只能在"React“中调用。

https://reactjs.org/docs/hooks-rules.html#only-call-hooks-from-react-functions

“不要从正规的JavaScript函数调用钩子。”

这就产生了一个问题,即什么才能准确地区分React函数和普通js函数。它是一个JSX元素的返回吗?这些职能如何:

代码语言:javascript
复制
function F1() { return <div>hello</div> } // certainly can use hooks 

function F2() { return F1() }   // can use hooks? is a react function? is a regular js function?
function F2() { return <F1 /> } // makes no difference, right?

function F3(s) { return <div>{s}</div> } // is a react function because uses jsx?  

function F4() { return F3("bugs bunny") }

function F5({s}) { return <div>{s}</div> }

它们都返回一个JSX元素。但我不确定f2或f4是否真的是响应函数并参与钩子连接。我们通过辩论的方式应该无关紧要。所以问题是:到底是什么造成了不同?

(我知道JSX,超文本是如何工作的,不需要解释这些基本原理。我只是没有研究钩子系统的内部结构。)

EN

回答 2

Stack Overflow用户

发布于 2022-09-01 18:02:15

函数是否是一个组件取决于您将如何使用该函数。您是否计划将其呈现为JSX元素,例如:<f1 />?如果是这样的话,它是一个react组件,它可以使用钩子(尽管您需要将它重命名为大写,就像在<F1 />中那样)。在呈现过程中,function将调用您的函数,但只在它设置了适当的内部状态以便钩子能够正确工作之后。

另一方面,如果您计划直接调用它(例如,f1()),您不能为它设置function的内部状态,而且function将不知道您正在调用该函数,因此它无法为您完成设置。因此,在这种函数中调用钩子的唯一方法是在另一个组件呈现时只调用该函数。这被称为“自定义钩子”。它们是重用代码的一个非常有用的工具,但是您应该使用从use开始的命名约定,以便程序员和lint工具知道如何强制执行钩子规则。

票数 2
EN

Stack Overflow用户

发布于 2022-09-02 00:18:56

决定一个函数是一个反应函数、一个自定义函数还是一个常规函数,它定义了谁可以从哪里调用它。如果F1是一个React函数(functional ),您可以将它称为<F1 />,但不应该将其称为F1();如果F1是一个常规函数,则可以将其称为F1(),但不应将其称为<F1 />。命名约定(F1、f1或useF1)将帮助您区分您想要的哪种类型的函数,这有助于您和linter坚持这些规则;如果您违反了规则,事情可能会工作,但它们也可能在难以调试的方式中失败。

  • 反应函数(Function):来自createElement或JSX的调用。可以根据规则调用钩子,并应该返回createElement或JSX表达式。按惯例以上骆驼病例(Foo)命名。
  • 自定义钩子:从功能组件或其他自定义钩子调用。可以根据规则调用钩子,可以返回任何东西。按照惯例,以"use“(useFoo)开头的小写骆驼命名。
  • 正则函数:从任何地方调用。不应该调用钩子;可以返回任何东西。与往常一样,用下骆驼病例(foo)命名。

除了尼古拉斯塔的答案,你应该注意到<F1 />F1()是不一样的。来自"JSX代表对象“React的主要概念的标题/介绍JSX

Babel将JSX编译成React.createElement()调用。 这两个例子是相同的: const元素=(你好,世界!); const元素= React.createElement( 'h1',{className:‘问候’},‘你好,世界!’);

具体来说,这个例子是:

代码语言:javascript
复制
function F1() {
  return <F1>hello</F1>;
}

function F2() {
}

编译为这个JS

代码语言:javascript
复制
"use strict";

function F1() {
  return /*#__PURE__*/React.createElement(F1, null, "hello");
}

function F2() {}

React.createElement()**.** F1不调用F2,F1将F2传递给F1,因此createElement可以准确地调用F2,并且只有在准备好调用F2时才能调用F2,从而允许它创建一个新的内部状态(即钩子调用的历史记录)。所以当你像这样定义F2

代码语言:javascript
复制
// React function, returns JSX
function F2() {
  useState('Mary')           // 1. Initialize the name state variable with 'Mary'
  useEffect(persistForm)     // 2. Add an effect for persisting the form
  useState('Poppins')        // 3. Initialize the surname state variable with 'Poppins'
  useEffect(updateTitle)     // 4. Add an effect for updating the title
  useLogin()                 // 5 & 6
}

// Custom hook, can call hooks according to rules, named "use" by convention
function useLogin() {
  const [user, setUser] = useState(getDefaultUser());
  const [domain, setDomain] = useState(getDomain());
}

// Normal function, can't call hooks
function getDefaultUser() {
  return "defaultUser";
}

...then React可以为特定的组件调用生成一个新的钩子状态,调用F2本身,然后得到一个类似于[useState, useEffect, useState, useEffect, useState(useLogin:user), useState(useLogin:domain)]的内部状态。由于钩子的规则禁止条件和循环,如果您做对了,每次调用F2都会得到这六个条目。如果您使用像getDefaultUser()这样的“常规Javascript函数”中的钩子,它可能会意外地工作,但是很难理解它的用法和遵守规则。

因此,您是决定函数的哪种类型的人,所有这些都是为了保持状态可预测。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73573550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档