鉴于此组件:
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
语法的情况下添加构造函数来定义状态?
答案 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)
}
此代码使用钩子从有状态类转换为函数,最初是在构造函数中设置默认属性-但是函数没有构造函数,并且每次组件重新渲染时都会进行检查:
useState
如您所见,这将导致无限循环。解决方案确实非常简单。这是与原始版本的模拟差异。
- 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')
}, []);