我目前正在React中学习钩子概念,并试图理解下面的示例。
DisplayNameGenerator
以上示例在处理程序函数参数本身上增加了计数器。如果我想在事件处理函数中修改计数值怎么办
请考虑以下示例
import { 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>
);
}
答案 0 :(得分:13)
React hooks是一种新方法(仍在开发中),它无需使用类即可访问诸如state
之类的react的核心功能,在您的示例中,如果您想直接在计数器中增加计数器处理程序函数,而无需直接在onClick
道具中指定它,您可以执行以下操作:
...
const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState(...);
...
const setCount = () => {
setCounter(count + 1);
setMoreStuff(...);
...
};
和onClick:
<button onClick={setCount}>
Click me
</button>
I wrote a complete article about hooks with multiple examples(包括计数器),例如this codepen,我使用了useState
,useEffect
,useContext
和自定义钩子。该文档还很好地说明了state hook和其他挂钩的工作原理,希望对您有所帮助。
更新: Hooks are not longer a proposal,由于版本 16.8 现已可以使用,因此React网站上有一个部分可以回答一些{ {3}}。
答案 1 :(得分:6)
useState
是0.16.7
版本中可用的内置react挂钩之一。
useState
仅应在功能组件内部使用。 useState
是我们需要内部状态并且不需要实现更复杂的逻辑(例如生命周期方法)的一种方式。
const [state, setState] = useState(initialState);
返回一个有状态值,以及一个更新它的函数。
在初始渲染期间,返回的状态(状态)与 作为第一个参数(initialState)传递的值。
setState函数用于更新状态。它接受一个新的 状态值,并重新渲染组件。
请注意,useState
钩子回调用于更新状态,与组件this.setState
相比 。为了说明不同之处,我准备了两个示例。
class UserInfoClass extends React.Component {
state = { firstName: 'John', lastName: 'Doe' };
render() {
return <div>
<p>userInfo: {JSON.stringify(this.state)}</p>
<button onClick={() => this.setState({
firstName: 'Jason'
})}>Update name to Jason</button>
</div>;
}
}
// Please note that new object is created when setUserInfo callback is used
function UserInfoFunction() {
const [userInfo, setUserInfo] = React.useState({
firstName: 'John', lastName: 'Doe',
});
return (
<div>
<p>userInfo: {JSON.stringify(userInfo)}</p>
<button onClick={() => setUserInfo({ firstName: 'Jason' })}>Update name to Jason</button>
</div>
);
}
ReactDOM.render(
<div>
<UserInfoClass />
<UserInfoFunction />
</div>
, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
使用setUserInfo
回调时将创建新对象。请注意,我们丢失了lastName
键值。为了解决这个问题,我们可以在useState
内部传递函数。
setUserInfo(prevState => ({ ...prevState, firstName: 'Jason' })
查看示例:
// Please note that new object is created when setUserInfo callback is used
function UserInfoFunction() {
const [userInfo, setUserInfo] = React.useState({
firstName: 'John', lastName: 'Doe',
});
return (
<div>
<p>userInfo: {JSON.stringify(userInfo)}</p>
<button onClick={() => setUserInfo(prevState => ({
...prevState, firstName: 'Jason' }))}>
Update name to Jason
</button>
</div>
);
}
ReactDOM.render(
<UserInfoFunction />
, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
与在类组件中找到的setState方法不同,useState可以 不会自动合并更新对象。您可以复制此 通过将功能更新程序形式与对象传播相结合来实现行为 语法:
setState(prevState => { // Object.assign would also work return {...prevState, ...updatedValues}; });
有关useState
的更多信息,请参见official documentation。
答案 2 :(得分:4)
useState()
是一个React钩子。挂钩使在函数组件内部使用状态和可变性成为可能。
虽然不能在类内部使用钩子,但是可以使用功能之一包装类组件并使用其中的钩子。这是将组件从类迁移到函数形式的绝佳工具。这是一个完整的示例:
在此示例中,我将使用计数器组件。就是这样:
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = { count: props.count };
}
inc() {
this.setState(prev => ({count: prev.count+1}));
}
render() {
return <button onClick={() => this.inc()}>{this.state.count}</button>
}
}
ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>
这是一个具有计数状态的简单类组件,状态更新由方法完成。这是类组件中非常常见的模式。第一件事是使用具有相同名称的功能组件包装它,该组件将其所有属性委派给包装的组件。另外,您还需要在函数return中呈现包装的组件。在这里:
function Hello(props) {
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = { count: props.count };
}
inc() {
this.setState(prev => ({count: prev.count+1}));
}
render() {
return <button onClick={() => this.inc()}>{this.state.count}</button>
}
}
return <Hello {...props}/>
}
ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>
这是完全相同的组件,具有相同的行为,相同的名称和相同的属性。现在让我们将计数状态提升到功能组件。就是这样:
function Hello(props) {
const [count, setCount] = React.useState(0);
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = { count: props.count };
}
inc() {
this.setState(prev => ({count: prev.count+1}));
}
render() {
return <button onClick={() => setCount(count+1)}>{count}</button>
}
}
return <Hello {...props}/>
}
ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>
<div id='root'></div>
请注意,方法inc
仍然存在,不会伤害任何人,实际上是无效代码。这就是想法,只是保持提升状态。完成后,您可以删除类组件:
function Hello(props) {
const [count, setCount] = React.useState(0);
return <button onClick={() => setCount(count+1)}>{count}</button>;
}
ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>
<div id='root'></div>
尽管这样做可以在类组件内部使用钩子,但我不建议您这样做,除非您像在本示例中那样进行迁移。函数和类组件的混合会使状态管理变得一团糟。希望对您有帮助
最好的问候
答案 3 :(得分:3)
useState
是React v16.8.0中可用的钩子之一。基本上,它使您可以将原本没有状态/功能的组件变成可以具有自己状态的组件。
在最基本的级别上,它是通过以下方式使用的:
const [isLoading, setLoading] = useState(true);
然后,您可以通过传递布尔值来调用setLoading
。
这是拥有“有状态”功能组件的一种很酷的方法。
答案 4 :(得分:2)
挂钩是@Override
public void onBackPressed() {
startActivity(new Intent(Activity_D.this,Activity_A.class));
finishAffinity();
}
中的一项新功能,React v16.7.0-alpha
是“挂钩”。 useState
设置any变量的默认值,并在函数component(PureComponent函数)中进行管理。 useState()
设置计数0的默认值。您可以使用ex : const [count, setCount] = useState(0);
到setCount
或incriment
的值。 decriment
增加计数值。DOC
答案 5 :(得分:2)
useState
挂钩的语法很简单。
const [value, setValue] = useState(defaultValue)
如果您不熟悉此语法,请转到here。
我建议您阅读documentation。其中有很多例子,举世无双。
import { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
// its up to you how you do it
const buttonClickHandler = e => {
// increment
// setCount(count + 1)
// decrement
// setCount(count -1)
// anything
// setCount(0)
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick={buttonClickHandler}>
Click me
</button>
</div>
);
}
答案 6 :(得分:2)
useState()是示例内置的React挂钩,可让您在功能组件中使用状态。在React 16.7之前这是不可能的。
useState函数是一个内置的挂钩,可以从react包中导入。它允许您向功能组件添加状态。使用功能组件内部的useState挂钩,您可以创建一条状态,而无需切换到类组件。
注意:请注意,挂钩目前处于Alpha版本,因此尚未准备就绪。这也意味着API可能会更改。
答案 7 :(得分:2)
useState是一个钩子,可用于将状态添加到功能组件。它接受作为状态属性初始值的参数,并返回状态属性的当前值和能够更新该状态属性的方法。
以下是一个简单的示例:
import React, {useState} from react
function HookCounter {
const [count, stateCount]= useState(0)
return(
<div>
<button onClick{( ) => setCount(count+1)}> count{count}</button>
</div>
)
}
useState接受状态变量的初始值(在这种情况下为零),并返回一对值。状态的当前值称为count,可以更新状态变量的方法称为setCount。
答案 8 :(得分:1)
感谢loelsonk,我这样做了
const [dataAction, setDataAction] = useState({name: '', description: ''});
const _handleChangeName = (data) => {
if(data.name)
setDataAction( prevState => ({ ...prevState, name : data.name }));
if(data.description)
setDataAction( prevState => ({ ...prevState, description : data.description }));
};
....return (
<input onChange={(event) => _handleChangeName({name: event.target.value})}/>
<input onChange={(event) => _handleChangeName({description: event.target.value})}/>
)
答案 9 :(得分:1)
基本上,React.useState(0)
神奇地发现它应该返回元组count
和setCount
(一种更改count
的方法)。参数useState
用来设置count
的初始值。
const [count, setCount] = React.useState(0);
const [count2, setCount2] = React.useState(0);
// increments count by 1 when first button clicked
function handleClick(){
setCount(count + 1);
}
// increments count2 by 1 when second button clicked
function handleClick2(){
setCount2(count2 + 1);
}
return (
<div>
<h2>A React counter made with the useState Hook!</h2>
<p>You clicked {count} times</p>
<p>You clicked {count2} times</p>
<button onClick={handleClick}>
Click me
</button>
<button onClick={handleClick2}>
Click me2
</button>
);
基于Enmanuel Duran的示例,但显示了两个计数器并将lambda函数作为常规函数编写,因此某些人可能会更容易理解。
答案 10 :(得分:1)
React useState 是 React Hook,可让您管理功能组件内的状态。
例如:
import React, { useState } from 'react'
const Example = () => {
// create the "counter" state
const [count, setCount] = useState(0)
return (
<div>
<p>Button clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Count + 1
</button>
</div>
)
}
export default Example
使用 useState,您可以轻松创建有状态的功能组件。
旧的等效方式,使用带有 Component
类和 setState
的类组件是:
import React, { Component } from 'react'
class Example extends Component {
constructor(props) {
super(props)
this.state = { count: 0 }
}
render() {
const { count } = this.state
return (
<div>
<p>Button clicked {count} times</p>
<button onClick={() => this.setState({ count: count + 1 })}>
Count + 1
</button>
</div>
)
}
}
export default Example
来源:
链接:
答案 11 :(得分:0)
上面提供的答案很好,但是我只想插手一下,useState
是异步的,因此,如果您的下一个状态取决于您以前的状态,则最好传递useState
一个回调。请参见下面的示例:
import { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
// passing a callback to useState to update count
<button onClick={() => setCount(count => count + 1)}>
Click me
</button>
</div>
);
}
如果您的新状态依赖于旧状态的计算,这是推荐的方法。
答案 12 :(得分:0)
useState是一个Hook,可让您在功能组件中使用状态变量。
React中有两种类型的组件:类和功能组件。
类组件是从React.Component扩展的ES6类,可以具有状态和生命周期方法:
class Message extends React.Component {
constructor(props) {
super(props);
this.state = {
message: ‘’
};
}
componentDidMount() {
/* ... */
}
render() {
return <div>{this.state.message}</div>;
}
}
功能组件是仅接受参数作为组件属性并返回有效JSX的函数:
function Message(props) {
return <div>{props.message}</div>
}
// Or as an arrow function
const Message = (props) => <div>{props.message}</div>
如您所见,没有状态或生命周期方法。
答案 13 :(得分:0)
让我们用简单的方式很容易理解 useState
假设我们有反应代码:-
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Test from './components/Test.jsx'
ReactDOM.render(
<div>
<Test />
</div>
,
document.getElementById('root')
);
Test.jsx
import React from "react";
function Test() {
var x = 5;
function update() {
console.log(x);
return x++;
}
return (
<div>
<h1>{x}</h1>
<button onClick={update}>click</button>
</div>
);
}
export default Test;
这里,页面将显示 5 ,虽然我们通过点击按钮调用更新功能,因为我们更新 x 而不是在 h1 标签之间,但实际上,每当我们点击时,x 都会不断变化,但是它可以在控制台上看到
see result and check console by clicking this link
这里 usState 神奇地工作,
Test.jsx 使用 useState
import React, { useState } from "react";
function Test() {
var x = 5;
const [value, setValue] = useState(x);
function update() {
setValue(value + 1);
}
return (
<div>
<h1>{value}</h1>
<button onClick={update}>click</button>
</div>
);
}
export default Test;
see result by clicking this link
这里,通过点击按钮,值会不断更新,因为这里我们使用 useState ,它是一个返回两件事的函数,一个是当前状态值,另一个是是 function ,如果我们向这个 function 传递任何值,它将更新 current state vlue 和 current state value 更新无需编写任何额外代码即可在任何地方使用它的价值。