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

时间:2017-05-30 13:39:41

标签: reactjs ecmascript-6

鉴于此组件:

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

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

6 个答案:

答案 0 :(得分:7)

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

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

无状态:

var React = require('react');

const Stateless = ({name}) => (
  <div>{`Hi ${name}`}</div>
);

有状态:

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

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.data}.</h2>
      </div>
    );
  }
}

答案 1 :(得分:4)

现在我们有了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)
}

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

  1. 呼叫useState
  2. 触发器重新呈现
  3. useEffect被触发
  4. 父母被称为设定道具
  5. 道具更新,以便子级再次渲染
  6. GOTO 1

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

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

- if (props.value) {
-   setValue(props.value)
- }

基本上,只需从道具初始化状​​态即可,除非响应某种事件或回调,否则不要像调用useState那样愚蠢的事情。

答案 2 :(得分:2)

你没有。示例中的组件类型称为“无状态功能组件”。它没有状态也没有生命周期方法。如果您希望组件具有状态,则必须将其编写为类组件。

答案 3 :(得分:2)

您可以将useState设置为功能组件内部的第一行,并将功能添加为“初始值”:

const MyComponentName = props => {
  useState(() => {
    console.log('this will run the first time the component renders!');
  });
  return <div>my component!</div>;
};

答案 4 :(得分:1)

要在FC中模拟构造函数,请使用useEffect。

useEffect(() => {
  ... here your init code
}, []);

就是这样! EZ!该useEffect仅在组件加载时运行一次,之后再运行,只是不要忘记在最后添加方括号。

答案 5 :(得分:0)

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

useMemo(() => {
  console.log('This is useMemo')
}, []);