reactjs 为什么未定义React函数组件的“this

xghobddn  于 2023-01-08  发布在  React
关注(0)|答案(2)|浏览(253)

我在React的Arrow函数组件中测试了“this”变量。
我希望“this”值可以是全局变量,无论何时调用函数组件。
因为据我所知,箭头函数中的'this'在声明箭头函数时是绑定的,而'this'是由词法作用域规则确定的。
词法作用域的结尾是全局作用域,因此“this”可能是全局变量。
我错过了什么?谢谢。

export default (props) => {

  console.log(this)

  return (
    <div>react this test</div>
  )
}
fhg3lkii

fhg3lkii1#

函数组件可以使用箭头函数() => {}(如上面的问题所示)或正则函数表达式/声明(如function Foo() {})来编写。要理解为什么会出现上述行为,首先要了解React组件(通常)是在ES6 modules中编写的。

为什么thisundefined在箭头函数组件中?

模块的一个属性是this在“模块作用域”的顶层是undefined,这个行为与常规脚本不同:

<!-- A "module" is what react component code is usually written in -->
<script type="module">
  console.log("Module code (react code) this:", this); // undefined
  //                                             ^
  const App = () => { // example component       |  
     this // --- taken from surrounding scope ---+
  }
</script>

上面的例子展示了this在模块范围内使用时如何默认为undefined,而不是像在标准脚本中那样默认为全局对象(如window)。
在arrow函数内部,this的值取自声明arrow函数的周围作用域。在您的示例中,这是模块的顶级,因此this采用undefined的值。

为什么thisundefined在常规函数组件中?

与上面的例子不同,function App() {}这样的函数表达式/声明也可以用来定义我们的组件,在这个例子中,你会看到this在组件中也是undefined,但是,这种情况的原因与箭头函数组件中的undefined不同。
要理解为什么会这样,模块的另一个重要属性是它们自动运行在strict mode中(强调我的):
另外,请注意,在模块内部定义的脚本部分与标准脚本中定义的脚本部分可能会有不同的行为。这是因为模块会自动使用严格模式

  • MDN语言
    在严格模式下,如果this在函数被调用时没有被绑定,则函数的this默认为undefined,而在非严格/宽松模式下,它默认为全局对象(例如浏览器中的window):
    但是,在严格模式下,如果在进入执行上下文时未设置此的值,则它将保持为undefined,如下面的示例所示
function f2() {
  'use strict'; // see strict mode
  return this;
}

console.log(f2() === undefined); // true
  • MDN语言
    function App() {}这样的正则函数表达式/声明有它们自己的this值,并根据函数的调用方式进行设置。对于函数组件,React以不设置this值的方式调用它们。在不以严格模式运行的标准脚本中,这将导致函数组件的this默认为全局对象(例如:window),但是,因为我们在一个模块中,该行为不再适用。相反,由于模块自动在严格模式下运行,并且React在调用组件时没有设置this,因此this值默认为undefined
    当你使用函数组件时,你不应该引用this,而应该用途:
  • 诸如useState()的钩子来管理状态
  • event argument在使用事件处理程序(而不是this)时通过.target/.currentTarget属性访问元素
  • props对象作为参数传递到函数组件中,以访问props(而不是this.props)。
mutmk8jj

mutmk8jj2#

在功能组件中不能使用,也没有必要,可以直接访问props,如果需要状态可以使用hook。

import React, { useState } from 'react';

export default (props) => {
  const [state, setState] = useState(/* initial state here */);
  console.log(props, state)

  return (
    <div>react this test</div>
  )
}

this在基于类的组件中的钩子之前使用:

class MyClass extends React.Component {
   render () {
     console.log(this.props, this.state);
   }
}

相关问题