Reputation: 607
I am trying to create constants in react as follows:
const [firstFocus, setFirstFocus] = React.useState(false);
const [lastFocus, setLastFocus] = React.useState(false);
The constants are being used in the code as follows:
import React, { Component } from 'react'
import axios from 'axios'
import {
Button,
Card,
CardHeader,
CardBody,
CardFooter,
Form,
Input,
InputGroupAddon,
InputGroupText,
InputGroup,
Container,
Col
} from "reactstrap";
class PostForm extends Component {
constructor(props) {
super(props)
this.state = {
email: '',
password: ''
}
}
changeHandler = (e) => {
this.setState({ [e.target.name]: e.target.value })
}
submitHandler = (e) => {
e.preventDefault()
console.log(this.state)
axios.post('https://jsonplaceholder.typicode.com/posts', this.state)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
}
render() {
const { email, password } = this.state
**const [firstFocus, setFirstFocus] = React.useState(false);
const [lastFocus, setLastFocus] = React.useState(false);**
return (
<div>
<Col className="ml-auto mr-auto" md="4">
<Card className="card-login card-plain">
<Form onSubmit={this.submitHandler} className="form">
<CardHeader className="text-center">
</CardHeader>
<CardBody>
<InputGroup
className={
"no-border input-lg"
}
>
<InputGroupAddon addonType="prepend">
<InputGroupText>
<i className="now-ui-icons ui-1_email-85"></i>
</InputGroupText>
</InputGroupAddon>
<Input
placeholder="Email"
type="text"
name="email"
value={email}
onChange={this.changeHandler}
// onFocus={() => setFirstFocus(true)}
// onBlur={() => setFirstFocus(false)}
></Input>
</InputGroup>
<InputGroup
className={
"no-border input-lg"
}
>
<InputGroupAddon addonType="prepend">
<InputGroupText>
<i className="now-ui-icons ui-1_lock-circle-open"></i>
</InputGroupText>
</InputGroupAddon>
<Input
placeholder="Password"
type="password"
name="password"
value={password}
onChange={this.changeHandler}
// onFocus={() => setLastFocus(true)}
// onBlur={() => setLastFocus(false)}
></Input>
</InputGroup>
</CardBody>
<CardFooter className="text-center">
<Button
block
className="btn-round"
color="info"
type="submit"
size="lg"
>
Get Started
</Button>
<div className="pull-right">
<h6>
<a
className="link"
href="#pablo"
onClick={e => e.preventDefault()}
>
Need Help?
</a>
</h6>
</div>
</CardFooter>
</Form>
</Card>
</Col>
</div>
)
}
}
export default PostForm
However, when I try to do this I get the following error:
Invalid hook call. Hooks can only be called inside of the body of a function component.
I created another constant there for email and password and it worked just fine so I'm not sure why my useState constants aren't working. Any help or guidance is much appreciated as I am very new to react. Thanks!
Upvotes: 38
Views: 94416
Reputation: 418
This worked for me, I just declared index & setIndex as follows. Might be a dirty hack, but hey 🤷♂️
render(){
const index = this.state.index;
const setIndex = (params) => this.setState({index: params});
return {
<Tab value={index} onChange={setIndex}>
<Tab.Item title="recent" />
<Tab.Item title="favorite" />
<Tab.Item title="cart" />
</Tab>
<TabView value={index} onChange={setIndex} >
<TabView.Item style={{ backgroundColor: 'red', width: '100%' }}>
<Text h1>recent</Text>
</TabView.Item>
<TabView.Item style={{ backgroundColor: 'blue', width: '100%' }}>
<Text h1>Favorite</Text>
</TabView.Item>
<TabView.Item style={{ backgroundColor: 'green', width: '100%' }}>
<Text h1>Cart</Text>
</TabView.Item>
</TabView>
}
}
Upvotes: 2
Reputation: 49180
Another way is to use hooks in a functional component and then import this functional component in a class component.
export default class LikeButton extends Component {
render() {
return <Like />;
}
}
function Like() {
const [like, setLike] = useState(100);
const [liked, toggleLike] = useState(false);
const handleLike = () => {
if (liked == false) {
setLike(like + 1);
toggleLike(true);
} else {
setLike(like - 1);
toggleLike(false);
}
};
return (
<>
<div>
<h2>Like Button</h2>
<button
onClick={() => handleLike()}
className={`like-button ${liked == true ? "liked" : ""}`}
>
Like | <span className="likes-counter">{like}</span>
</button>
</div>
</>
);
}
Upvotes: 0
Reputation: 2047
In react, we have 2 ways to build components: classes and functions.
Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.
Using the State Hook:
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Equivalent Class Example:
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
Upvotes: 84
Reputation: 504
Officially you can't use hook on class component. But of course there is some trick if you want use useState on class component
example, you can't do this
class Example extends React.Component {
_renderCounter = () => {
//
// YOU CAN'T DO THIS
// REACT WONT ALLOW YOU
//
const [count, setCount] = useState(0);
return <div>{ count }</div>
}
render() {
return(
<div>{ this._renderCounter() }</div>
);
}
}
But, with small trick you can do this. React will allow you
class Example extends React.Component {
_renderCounter = () => () => {
const [count, setCount] = useState(0);
return <div>{ count }</div>
}
render() {
const MyInlineHook = this._renderCounter();
return(
<div><MyInlineHook /></div>
);
}
}
With this trick, you can access to this
and props
of the class component. :)
Upvotes: 13
Reputation: 1442
Hooks can only be used in functional components, you're using class component.
For more information and how to implement it please check this article Link
Upvotes: 2
Reputation: 125
You are trying to use useState, which is a React hook, inside a class component. This won't work. Hooks can only be used in functional components.
Upvotes: 5