无法在类组件 React.js 中使用 useState
Posted
技术标签:
【中文标题】无法在类组件 React.js 中使用 useState【英文标题】:Unable to use useState in class component React.js 【发布时间】:2020-03-31 22:44:36 【问题描述】:我正在尝试在 react 中创建常量,如下所示:
const [firstFocus, setFirstFocus] = React.useState(false);
const [lastFocus, setLastFocus] = React.useState(false);
代码中使用的常量如下:
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
但是,当我尝试这样做时,我收到以下错误:
无效的挂钩调用。 Hooks 只能在 a 的主体内部调用 功能组件。
我在那里为电子邮件和密码创建了另一个常量,它工作得很好,所以我不确定为什么我的 useState 常量不起作用。非常感谢任何帮助或指导,因为我对反应非常陌生。谢谢!
【问题讨论】:
【参考方案1】:在 react 中,我们有 2 种方式来构建组件:类和函数。
DOCS
Hooks 是 React 16.8 中的新增功能。它们让您无需编写类即可使用状态和其他 React 功能。
使用状态钩子:
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>
);
等效类示例:
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>
);
【讨论】:
【参考方案2】:官方不能在类组件上使用钩子。但是,如果你想在类组件上使用 useState,当然有一些技巧
例如,你不能这样做
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>
);
但是,通过小技巧,您可以做到这一点。 React 会让你
class Example extends React.Component
_renderCounter = () => () =>
const [count, setCount] = useState(0);
return <div> count </div>
render()
const MyInlineHook = this._renderCounter();
return(
<div><MyInlineHook /></div>
);
通过这个技巧,你可以访问类组件的this
和props
。 :)
【讨论】:
您如何以这种方式访问 setCount 方法?【参考方案3】:您正在尝试在类组件中使用 useState,它是一个 React 钩子。这行不通。 Hooks 只能用在函数式组件中。
【讨论】:
你知道类组件的等效实现/方法是什么吗? 您需要在您的构造函数中创建一个名为 this.state 的状态对象。然后,您可以通过调用 this.setState 在方法中更改它。在这里解释会很长,但你可以在这里查看文档reactjs.org/docs/state-and-lifecycle.html 或谷歌在类组件中初始化状态【参考方案4】:Hooks 只能用在函数式组件中,你使用的是类组件。
有关更多信息以及如何实施,请查看本文Link
【讨论】:
【参考方案5】:这对我有用,我刚刚声明 index 和 setIndex 如下。可能是一个肮脏的黑客,但是嘿?♂️
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>
【讨论】:
【参考方案6】:另一种方法是在功能组件中使用钩子,然后将这个功能组件导入到类组件中。
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>
</>
);
【讨论】:
以上是关于无法在类组件 React.js 中使用 useState的主要内容,如果未能解决你的问题,请参考以下文章
React.js useState hook 导致过多的重新渲染并且无法更新我的状态