如何使用功能组件指定构造函数(胖箭头语法)?

Ken*_*yer 12 ecmascript-6 reactjs

鉴于此组件:

import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'

const NewGoalInput = props => {
  return (
    <input type="text" onKeyUp={handleKeyUp}/>
  )
}

const handleKeyUp = (e) => {
  if (e.key === "Enter") {
    // TODO Add goal
  }
}

export default NewGoalInput
Run Code Online (Sandbox Code Playgroud)

如何在不使用extends React.Component语法的情况下添加构造函数来定义状态?

Hev*_*var 10

由于它是无状态组件,因此它没有组件生命周期.因此,您无法指定constructor.

你必须扩展React.Component以创建一个有状态的组件,然后需要一个构造函数,你将能够使用state.

无状态:

import React from "react"

const Stateless = ({name}) => (
  <div>{`Hi ${name}`}</div>
);
Run Code Online (Sandbox Code Playgroud)

有状态:

class Stateful extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  componentDidMount() {
    const { count } = this.state;
    document.title = `You've clicked ${count} times.`;
  }

  componentDidUpdate() {
    const { count } = this.state;
    document.title = `You've clicked ${count} times.`;
  }

  render() {
    const { count } = this.state;
    return (
      <div>
        <p>You've clicked {count} times.</p>
        <button onClick={() => this.setState({ count: count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 很棒的解释。然而,这并不能完全回答问题,因为“构造函数”实际上并不是生命周期方法的一部分,这意味着“useEffect”钩子对功能组件中的“构造函数”创建没有帮助。 (2认同)

Ric*_*gen 10

现在我们有了useState钩子,答案有点过时了。我遇到了这个问题,因为我做错了什么。这是我正在做的一些简化代码。

// set an initial state
const [ value, setValue ] = useState(0)

// gets called after component is re-rendered
useEffect(() => {
   // callback to parent that set props
   props.update()
})

// if we have an existing value passed in
if (props.value) {
   setValue(props.value)
}
Run Code Online (Sandbox Code Playgroud)

这段代码使用钩子从有状态的类转换为函数,最初是在构造函数中设置默认属性-但函数没有构造函数,并且每次组件重新渲染时都会进行检查:

  1. 来电 useState
  2. 触发重新渲染
  3. 触发useEffect
  4. 家长叫来设置道具
  5. 道具更新,以便孩子再次渲染
  6. 转到1

如您所见,这将导致无限循环。解决方案确实非常简单。这是与原始版本的模拟差异。

- const [ value, setValue ] = useState(0)
+ const [ value, setValue ] = useState(props.value || 0)

- if (props.value) {
-   setValue(props.value)
- }
Run Code Online (Sandbox Code Playgroud)

基本上,只是从道具初始化状​​态,useState除了响应某种事件或某种回调之外,不要做诸如调用之类的愚蠢的事情。


Huy*_*Huy 7

您可以使用useMemo钩子(如下)来演示功能组件的构造函数。有人建议使用useEffect ,但它会在渲染后调用。

useMemo(() => {
  console.log('This is useMemo')
}, []);
Run Code Online (Sandbox Code Playgroud)