我目前正在React中学习钩子概念,并试图理解以下示例。
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>
);
}
上面的示例在处理程序函数参数本身上增加计数器。如果我想在事件处理函数中修改计数值怎么办
考虑以下示例:
setCount = () => {
//how can I modify count value here. Not sure if I can use setState to modify its value
//also I want to modify other state values as well here. How can I do that
}
<button onClick={() => setCount()}>
Click me
</button>
React钩子是访问React核心功能的一种新方法(仍在开发中),例如state
无需使用类,在您的示例中,如果您想直接在处理函数中增加计数器而不在onClick
prop中直接指定它,您可以可以做类似的事情:
...
const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState(...);
...
const setCount = () => {
setCounter(count + 1);
setMoreStuff(...);
...
};
和onClick:
<button onClick={setCount}>
Click me
</button>
让我们快速解释一下这一行的情况:
const [count, setCounter] = useState(0);
useState(0)
返回一个元组,其中第一个参数count
是计数器的当前状态,并且setCounter
是允许我们更新计数器状态的方法。我们可以使用该setCounter
方法来更新count
任何地方的状态-在这种情况下,我们在setCount
函数中使用它可以做更多的事情;带有钩子的想法是,我们能够使我们的代码保持更多功能,并且在不需要/不需要时避免使用基于类的组件。
我写了多个例子挂钩一个完整的文章(包括计数器)如本codepen,我利用了useState
,useEffect
,useContext
,和自定义挂钩。我可以深入了解有关钩子如何工作的详细信息,但是文档在解释状态钩子和其他钩子方面做得很好,希望对您有所帮助。
更新: 钩子不再是一个建议,因为版本16.8可以使用了,因此React网站上有一个部分可以回答一些FAQ。
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
请参见官方文档。
useState
hook的语法很简单。
const [value, setValue] = useState(defaultValue)
如果您不熟悉此语法,请转到此处。
我建议您阅读文档。其中有大量示例,所以有很好的解释。
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>
);
}
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>
尽管这使在类组件内部使用挂钩成为可能,但我不建议您这样做,除非您像在本示例中那样进行迁移。函数和类组件的混合会使状态管理变得一团糟。我希望这有帮助
最好的祝福
useState
是React v16.8.0中可用的钩子之一。基本上,它使您可以将原本没有状态/功能的组件变成可以拥有自己状态的组件。
在最基本的级别上,它是通过以下方式使用的:
const [isLoading, setLoading] = useState(true);
然后,这使您可以调用setLoading
传递布尔值。这是拥有“有状态”功能组件的一种很酷的方法。
useState()是内置的React挂钩示例,可让您在功能组件中使用状态。在React 16.7之前这是不可能的。
useState函数是一个内置的挂钩,可以从react包中导入。它允许您向功能组件添加状态。使用功能组件内部的useState挂钩,您可以创建一条状态,而无需切换到类组件。
挂钩是React v16.7.0-alpha
useState
“挂钩”中的一个新功能。useState()
设置any变量的默认值并在函数组件(PureComponent函数)中进行管理。 ex : const [count, setCount] = useState(0);
设置计数0的默认值。并且u可以使用setCount
toincrement
或decrement
该值。onClick={() => setCount(count + 1)}
增加计数值。DOC
谢谢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})}/>
)
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。
基本上,React.useState(0)
魔术师认为它应该返回元组count
and 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函数编写为常规函数,因此某些人可能会更容易理解。
上面提供的答案很好,但是让我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>
);
}
如果您的新状态依赖于旧状态的计算,则这是推荐的方法。
文章标签:javascript , react-hooks , react-native , react-state , reactjs
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!