Given this component:
import React from \'react\'
import ReactDOM from \'react-dom\'
import PropTypes from \'prop-types\'
const NewGoalInput = props => {
Since it's a stateless component it doesn't have the component lifecycle.
Therefor you can't specify a constructor
.
You have to extend React.Component
to create a stateful component which then will need a constructor and you'll be able to use the state
.
Update Since React 16.8.0 and Hooks got introduced there are more options.
Hooks are a new feature proposal that lets you use state and other React > features without writing a class. They are released in React as a part of > v16.8.0
Stateless:
import React from "react"
const Stateless = ({name}) => (
<div>{`Hi ${name}`}</div>
);
Stateful:
Has access to component lifecycle methods and local state.
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>
);
}
}
Using Hooks:
Able to use State Hook
and Effect Hook
.
If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.
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>
</>
);
}
Now that we have useState
and hooks the answers are kind of out of date. I came across this question because I was doing something wrong. Here's some simplified code of what I was doing.
// 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)
}
This code was converted from a stateful class to a function using hooks, originally setting the default props in the constructor - but functions don't have constructors and that check happens every time the component re-renders:
useState
As you can see this results in an infinite loop. The solution is really quite simple. Here's a mock diff from the original.
- const [ value, setValue ] = useState(0)
+ const [ value, setValue ] = useState(props.value || 0)
- if (props.value) {
- setValue(props.value)
- }
Basically, just initialise the state from the props and don't do silly things like calling useState
except in response to an event or callback of some type.
To simulate constructor in FC use useEffect.
useEffect(() => {
... here your init code
}, []);
That's it! EZ! This useEffect runs only once when the component loads and never runs after, just don't forget to add square brackets at the end.
You don't. The kind of component in your example is called "stateless functional component". It has no state and no lifecycle methods. If you want your component to be stateful you'll have to write it as a class component.
you could set a useState as the first line inside of your functional component and add a function as "initial value":
const MyComponentName = props => {
useState(() => {
console.log('this will run the first time the component renders!');
});
return <div>my component!</div>;
};