构造函数中的props state与简单state

4

我开始学习 React 时,我们可以简单地使用状态和创建对象,而不需要使用 constructor(props){ super(props)

现在,我看到许多库仍在使用

class Master extends Component {
  constructor(props){
    super(props)

我的第一个问题是,使用constructor(props)super(props)然后设置状态是否比直接创建状态对象更有优势?
第二个问题,我想在我正在制作的本地应用程序中实现react-native-slowlog
在整个代码中,我直接创建了状态对象而没有使用构造函数。 react-native-slowlog的文档显示了使用此方式。
class Master extends Component {
  constructor(props){
    super(props)
    slowlog(this, /.*/)

    this.state = this.getDataSource(props)
    this.shouldComponentUpdate = shouldComponentUpdate.bind(this)
  }
...
}

在构造函数中调用 slowlog(this, /.*/),我想知道是否可以避免在此处使用构造函数?或者我创建一个构造函数,在其中执行 slowlog(this, /.*/),然后在构造函数外部创建状态对象,这样可以吗?

class Master extends Component {
  constructor(){
    super() 
    slowlog(this, /.*/)
  } 


  state = {
    searchCoin: false
  }
3个回答

5
  • 为什么要使用 constructor(props){}super(props) 呢?

唯一的原因是当你想在构造函数中访问 this 时,需要这样做。参见 React 源代码

如果你传递:

class MyComponent extends React.Component {
     constructor(props) {
         super(props)

         console.log(this.props)
         // goood
     }
 }

如果您没有传递参数但调用了super

 class MyComponent extends React.Component {
     constructor(props) {
         super()

         console.log(this.props)
         // -> undefined

         // Props parameter is still available
         console.log(props)
         // good
     }

     render() {
         // No difference outside constructor
         console.log(this.props)
         // good
     }
 }

如果你不调用

class MyComponent extends React.Component {
     constructor(props) {
           console.log(this)
         // undefined
     }
 }

总结一下,这并不总是必需的。

  • 在构造函数中设置状态与在外部设置状态

这只是语法糖,因此没有区别。

构造函数仅在挂载时调用一次,因此您希望执行不希望在每次渲染中执行的操作。


我原本以为 OP 对 super()super(props) 不感兴趣,这只是粘贴的代码,但这是一个很好的观点。 - Estus Flask

3

如果只需要定义state,则可以使用class fields proposal跳过显式的constructor

class Master extends Component {
  state = { searchCoin: false };
  ...

这是 ES6 的语法糖:

class Master extends Component {
  constructor(props){
    super(props);
    this.state = { searchCoin: false };
  } 
  ...

关于state是定义为类字段还是构造函数体的一部分这个问题,实际上取决于个人口味;如果需要使用构造函数,则可以将其定义为构造函数的一部分。但是,定义为类字段需要键入更少的字符,因为它不包含this.

另外,请注意:

class Master extends Component {
  constructor(){
    super() 
    slowlog(this, /.*/)
  } 

  state = { searchCoin: false }
  ...

是一种语法糖,意为

class Master extends Component {
  constructor(){
    super() 
    this.state = { searchCoin: false };
    slowlog(this, /.*/)
  } 
  ...

类字段放在super之后、其他构造函数语句之前。如果期望slowlog首先运行,则此方法可能无法按预期工作。


由于我没有经常使用构造函数,所以在构造函数中调用redux操作this.props.CurrencyRate()而不是在componentDidMountcomponentWillMount中调用是否是一个好主意? - Alwaysblue
这取决于CurrencyRate的工作方式。componentWillMount已被弃用,建议使用constructor。如果它是异步的,并且在componentDidMount中与在constructor中的工作方式相同,则componentDidMount是正确的位置。 - Estus Flask
@KuchBhi 不要在 Api 调用中使用构造函数。React 提供构造函数的主要目的是进行预初始化状态、进行函数/对象绑定以及在您想要使用父级 props 预初始化状态时访问父级 props。建议您在 componentDidMount 中进行 Api 调用,并相应地进行 setState。 - Hemadri Dasari

1
如果您需要初始化状态或绑定函数,则只需使用构造函数。

如果您不初始化状态,也不绑定方法,则无需为React组件实现构造函数。 https://reactjs.org/docs/react-component.html#constructor

因此,对于您提供的库所做的事情,您确实需要在构造函数中调用它。它既初始化了状态,又绑定了shouldComponentUpdate函数。
但是,如果您没有绑定任何内容,您可以直接在属性上初始化状态,如下所示...

Typescript

class Master extends React.Component<any, any> {
  public readonly state = { someKey: "Initial Value" };
}

JavaScript

class Master extends React.Component {
  state = { someKey: "Initial Value" };
}

我不确定 this.getDataSource(props) 函数的作用,它是否只是 slowlog 提供的示例。但是在类属性和构造函数中都初始化状态是行不通的。因此,你可以按照你的示例所示的方式进行,或者从 componentDidMount 函数中调用该函数。
class Master extends React.Component {
  // initialize your state
  state = { someKey: "Initial Value" };

  constructor (props) {
    super(props)
    slowlog(this /*, */);

    this.shouldComponentUpdate = shouldComponentUpdate.bind(this);
  }

  componentDidMount() {
    const nextState = this.getDataSource(this.props);
    this.setState(nextState);
  }
}

需要注意的是,如果getDataSource返回一个promise,应该在组件挂载时调用它,而不是从构造函数中调用。

如果您需要从远程端点加载数据,则在此处实例化网络请求是一个好方法。https://reactjs.org/docs/react-component.html#componentdidmount


@estus,没问题,无论是TS、Flow还是JS,生命周期都是一样的。你可以只是移除类和状态的类型定义。 - kyle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接