如何指定具有功能组件的构造函数(粗箭头语法)?

IT技术 reactjs ecmascript-6
2021-04-15 02:24:03

鉴于此组件:

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个回答

由于它是一个无状态组件,它没有组件生命周期。因此你不能指定一个constructor.

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

更新 自从React 16.8.0和 Hooks 被引入以来,有更多的选择。

Hooks 是一个新的特性提案,它可以让你在不编写类的情况下使用状态和其他 React > 特性。它们作为 > v16.8.0 的一部分在 React 中发布

无国籍:

import React from "react"

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

有状态:

可以访问组件生命周期方法和本地状态。

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>
    );
  }
}

使用钩子:

能够使用State HookEffect Hook

如果您熟悉 React 类的生命周期方法,您可以将 useEffect Hook 视为 componentDidMount、componentDidUpdate 和 componentWillUnmount 的组合。

import React, { useState, useEffect } from "react";

const UsingHooks = () => {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You've clicked ${count} times.`;
  });

  return (
    // <> is a short syntax for <React.Fragment> and can be used instead of a wrapping div
    <>
      <p>You've clicked {count} times.</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </>
  );
}
很棒的解释。然而,这并不能完全回答这个问题,因为constructor它并不是生命周期方法的真正组成部分,这意味着useEffect钩子不能帮助constructor创建功能组件。
2021-06-11 02:24:03

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

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

  1. 电话 useState
  2. 触发重新渲染
  3. useEffect 被触发
  4. 调用 parent 来设置 props
  5. props 更新,所以 child 再次渲染
  6. 转到 1

如您所见,这会导致无限循环。解决方案真的很简单。这是与原始版本的模拟差异。

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

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

基本上,只需从 props 初始化状态,不要做愚蠢的事情,比如调用,useState除非响应某种类型的事件或回调。

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

const MyComponentName = props => {
  useState(() => {
    console.log('this will run the first time the component renders!');
  });
  return <div>my component!</div>;
};
如果您需要将“构造函数”中的任何值暴露给组件,请记住此函数的返回值是由 返回的数组中的第一项useState,如下所示:const [value] = useState(() => { /* ... */ return '123'; })
2021-06-19 02:24:03

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

React 的现代版本能够state使用功能组件进行管理hooks,这会使您的答案过时。
2021-06-03 02:24:03

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

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

而已!EZ!这个 useEffect 在组件加载时只运行一次,之后再也不运行,只是不要忘记在最后添加方括号。

它不是构造函数的替换,而是替换组件
2021-06-06 02:24:03
useEffect 钩子在渲染函数之后运行,因此即使您传递第二个参数(“方括号”),它们也不会提供与构造函数相同的功能。类组件中的构造函数甚至在第一次渲染调用之前运行
2021-06-08 02:24:03
蒂莫菲是对的。useEffect() 确实模仿 componentDidMount - 不是构造函数。您不能使用它来设置应该在之后呈现的初始数据,就像在基于类的构造函数中完成的那样。
2021-06-17 02:24:03
谢谢!学到了一些东西。
2021-06-21 02:24:03