React 函数式组件(不再使用 class 组件)中的箭头函数和常规函数有什么区别?
What is the difference between arrow functions and regular functions inside React functional components (no longer using class components)?
自从 React Hooks 之后,我决定放弃 React class 组件。我现在只处理钩子和功能组件。
简单问题:
我理解在 class 主体中使用箭头函数而不是常规函数的区别。箭头函数会自动绑定 (lexical this) 到我的 class 的实例,我不必将它绑定到构造函数。这个不错。
但由于我不再处理 classes,我想知道在功能组件内部执行以下操作有什么区别:
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>
);
}
问题
两者都很好。
性能有差异吗?我应该一种方式而不是另一种方式吗?它们是在每次渲染时都重新创建,对吗?
关于可能重复的注意事项
我真的不认为这是一个重复的问题。我知道关于箭头和正则之间的区别有很多问题,但我想从 React 功能组件的角度以及 React 如何处理它来了解。我找了一圈也没找到。
用于测试的代码片段
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'));
.div1 {
border: 1px solid blue;
cursor: pointer;
}
.div2 {
border: 1px solid blue;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
除了您已经指出的差异(词法作用域)之外,箭头函数(和函数表达式)未提升,因此在定义之前不能调用.看我的例子。在我看来这不是问题,因为依赖提升的代码更难推理。
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'));
<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>
由于您没有访问 this
上下文,因此两者的行为相同。
要了解更多信息,您可以查看 babel 是如何传输到 ECMA 的:
const handleClick2 = () => {
console.log('handleClick2 executed...');
this.x=3
}
将被转译为:
"use strict";
var _this = void 0;
var handleClick2 = function handleClick2() {
console.log('handleClick2 executed...');
_this.x = 3;
};
自从 React Hooks 之后,我决定放弃 React class 组件。我现在只处理钩子和功能组件。
简单问题:
我理解在 class 主体中使用箭头函数而不是常规函数的区别。箭头函数会自动绑定 (lexical this) 到我的 class 的实例,我不必将它绑定到构造函数。这个不错。
但由于我不再处理 classes,我想知道在功能组件内部执行以下操作有什么区别:
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>
);
}
问题
两者都很好。
性能有差异吗?我应该一种方式而不是另一种方式吗?它们是在每次渲染时都重新创建,对吗?
关于可能重复的注意事项
我真的不认为这是一个重复的问题。我知道关于箭头和正则之间的区别有很多问题,但我想从 React 功能组件的角度以及 React 如何处理它来了解。我找了一圈也没找到。
用于测试的代码片段
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'));
.div1 {
border: 1px solid blue;
cursor: pointer;
}
.div2 {
border: 1px solid blue;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
除了您已经指出的差异(词法作用域)之外,箭头函数(和函数表达式)未提升,因此在定义之前不能调用.看我的例子。在我看来这不是问题,因为依赖提升的代码更难推理。
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'));
<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>
由于您没有访问 this
上下文,因此两者的行为相同。
要了解更多信息,您可以查看 babel 是如何传输到 ECMA 的:
const handleClick2 = () => {
console.log('handleClick2 executed...');
this.x=3
}
将被转译为:
"use strict";
var _this = void 0;
var handleClick2 = function handleClick2() {
console.log('handleClick2 executed...');
_this.x = 3;
};