React 函数组件中的箭头函数和常规函数有什么区别(不再使用类组件)?

cbd*_*per 9 javascript reactjs react-hooks

从 React Hooks 开始,我决定放弃 React 类组件。我现在只处理钩子和功能组件。

简单的问题:

我理解在类体内使用箭头函数而不是常规函数之间的区别。箭头函数会自动绑定(词法 this)到我的类的实例,我不必在构造函数中绑定它。这很好。

但由于我不再处理类,我想知道在功能组件内部执行以下操作有什么区别:

function App() {

  // REGULAR FUNCTION
  function handleClick1() {
    console.log('handleClick1 executed...');
  }

  // ARROW FUNCTION
  const handleClick2 = () => {
    console.log('handleClick2 executed...');
  }

  return(
    <React.Fragment>
      <div className={'div1'} onClick={handleClick1}>
        Div 1 - Click me
      </div>
      <div className={'div2'} onClick={handleClick2}>
        Div 2 - Click me
      </div>
    </React.Fragment>
  );
}
Run Code Online (Sandbox Code Playgroud)

两者都工作正常。

性能上区别吗?我应该赞成一种方式而不是另一种方式吗?它们都在每次渲染时重新创建,对吗?


关于可能重复的注意事项

我真的不认为这是一个重复的问题。我知道关于箭头和正则之间的区别有很多问题,但我想从 React 功能组件的角度了解 React 是如何处理它的。我环顾四周,没有找到。


用于测试的代码片段

function App() {

  // REGULAR FUNCTION
  function handleClick1() {
    console.log('handleClick1 executed...');
  }

  // ARROW FUNCTION
  const handleClick2 = () => {
    console.log('handleClick2 executed...');
  }

  return(
    <React.Fragment>
      <div className={'div1'} onClick={handleClick1}>
        Div 1 - Click me
      </div>
      <div className={'div2'} onClick={handleClick2}>
        Div 2 - Click me
      </div>
    </React.Fragment>
  );
}
Run Code Online (Sandbox Code Playgroud)
function App() {
  
  function handleClick1() {
    console.log('handleClick1 executed...');
  }
  
  const handleClick2 = () => {
    console.log('handleClick2 executed...');
  }
  
  return(
    <React.Fragment>
      <div className={'div1'} onClick={handleClick1}>
        Div 1 - Click me
      </div>
      <div className={'div2'} onClick={handleClick2}>
        Div 2 - Click me
      </div>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
.div1 {
  border: 1px solid blue;
  cursor: pointer;
}

.div2 {
  border: 1px solid blue;
  cursor: pointer;
 }
Run Code Online (Sandbox Code Playgroud)

Phi*_*lip 6

除了您已经指出的差异(词法范围)之外,箭头函数(和函数表达式)不会被提升,因此在定义之前不能被调用。看我的例子。在我看来这不是问题,因为依赖提升的代码更难推理。

React 实际上并不关心你使用哪一个(它也无法检测到)。

const A = () => {
  const name = getName();
  
  function getName() {
    return 'praffn';
  }
  
  // Will not work
  // const getName = () => 'praffn';
  
  return <p>Hi, {name}</p>;
}

ReactDOM.render(<A/>, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)

  • 就我个人而言,我还没有发现函数提升在实践中是一个很大的问题(与“var”提升不同),并且我认为在那里使用“function”关键字使代码比几乎所有以“const”开头的代码更具可读性。(我怀疑 Facebook 在他们的例子中使用“函数”可能有类似的原因。)但正如 Phillip 已经指出的那样,这是一种风格偏好——两者都可以很好地工作。 (2认同)
  • @MattBrowne,我实际上更喜欢使用“function”关键字 - 对我来说它更具可读性。我通常只在单行函数和高阶函数中使用箭头函数。然而,如果可能的话,我会避免依赖吊装。 (2认同)

yka*_*gol 5

由于您没有访问this上下文,因此两者的行为都是相同的

要了解更多信息,您可以检查 babel 是如何转化为 ECMA 的:

 const handleClick2 = () => {
    console.log('handleClick2 executed...');
    this.x=3
 }
Run Code Online (Sandbox Code Playgroud)

将被转译为:

"use strict";

var _this = void 0;

var handleClick2 = function handleClick2() {
  console.log('handleClick2 executed...');
  _this.x = 3;
};
Run Code Online (Sandbox Code Playgroud)

链接到 babel 记事本