Given this component:
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
How do I add a constructor where I can define the state without using the extends React.Component
syntax?
When you're building functional components in React, there's a little feature from class-based components that simply has no out-of-the-box equivalent in functions. This feature is called a constructor.
In React, the constructor is called during component creation and before mounting. If you want to implement the constructor for a React component, call the super(props) method before any other statement. Otherwise, this. props will be undefined in the constructor and create bugs.
The constructor is a method used to initialize an object's state in a class. It automatically called during the creation of an object in a class. The concept of a constructor is the same in React. The constructor in a React component is called before the component is mounted.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With