useState
vue2通过data
,vue3中通过ref
,reactive
绑定响应式数据,来达到数据与视图同步更新的效果。
而在react中是通过useState
来实现的。
useState是什么?
useState
是react内置的hook,主要用于给组件添加状态变量。useState
会返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数。
下面是一个计时器的例子
import { useState } from 'react';
function App() {
// 声明一个叫 “count” 的 state 变量。
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
export default App;
useState 的两种更新方式
- 值更新
- 函数式更新
值更新就是上面例子中的写法,直接把值传递给setCount
函数,函数式更新是在setCount
参数中,写一个函数拿到当前状态的值,接着进行赋值。
接着通过计时器了解这两个的区别
import { useState } from 'react';
function App() {
// 声明一个叫 “count” 的 state 变量。
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1)
setCount(count + 1)
setCount(count + 1)
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick={handleClick}>
Click me
</button>
</div>
);
}
export default App;
结果:每点一次按钮 +1,
为什么不是每次+3呢?
这是因为在每个setCount
中的count的值都是当前的值,比如count为0,执行了3遍setCount(0 + 1)
所以这次更新count的结果是1
下面是函数式写法
import { useState } from 'react';
function App() {
// 声明一个叫 “count” 的 state 变量。
const [count, setCount] = useState(0);
const handleClick = () => {
setCount((count) => count + 1)
setCount((count) => count + 1)
setCount((count) => count + 1)
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick={handleClick}>
Click me
</button>
</div>
);
}
export default App;
结果:每点一次按钮 +3,
通过函数式的写法,每次调用setCount
函数时可以拿到本次更新count
的最新状态,这样就实现在一次更新时对数据的重复操作。
引用数据类型
上面演示的是值类型的数据,对于引用类型数据需要额外注意一点,
下面看一个例子
import { useState } from 'react';
function App() {
// 声明一个叫 info 的 state 变量。
const [info, setInfo] = useState({
name: '张三',
age: 18
});
const handleClick = () => {
info.name = '李四'
setInfo(info)
}
return (
<div>
<p>name: {info.name} age: {info.age}</p>
<button onClick={handleClick}>
Click me
</button>
</div>
);
}
export default App;
结果:点击按钮的时候数据并没有发生改变。如果绑定一个引用类型,使用更新函数时需要改变值的引用,也就是重新去定义新数据
示例:
import { useState } from 'react';
function App() {
// 声明一个叫 info 的 state 变量。
const [info, setInfo] = useState({
name: '张三',
age: 18
});
const handleClick = () => {
let newInfo = {...info}
newInfo.name = '李四'
setInfo(newInfo)
}
return (
<div>
<p>name: {info.name} age: {info.age}</p>
<button onClick={handleClick}>
Click me
</button>
</div>
);
}
export default App;
immutable 编程规范
Immutable 编程规范是一种编程范式,它要求在编写程序时避免对数据进行修改,而是应该创建新的数据副本来进行修改。这样做的好处是可以避免出现意外的数据修改,提高程序的可靠性和可维护性。Immutable 编程规范通常使用不可变数据结构来实现,例如不可变对象、不可变集合等。在许多函数式编程语言中,Immutable 编程规范是被广泛采纳的一种编程风格。
在react中也就是useState
创建的状态就是Immutable数据,是不可直接修改的,在修改的时候使用更新函数,而不要直接修改状态的值
另外推荐一个好用的第三方库,来约束你的行为
useImmer
安装方法:
npm install use-immer --save
使用的方式和功能与useState
类似,会规范你直接修改Immutable数据的行为
import { useImmer } from 'use-immer';
function App() {
const [user, setUser] = useImmer({
name : '张三',
age: 16
});
const handleClick = () => {
user.name = '李四'
setUser(user)
}
return (
<div>
<div>name: {user.name} age: {user.age}</div>
<button onClick={handleClick}>click</button>
</div>
)
}
export default App;
直接修改user.name
会报一下错误
另外使用useImmer声明的状态,推荐使用函数式写法可以拿到状态的值并修改,引用类型写法上相比useState
更加方便,使用这种方式去修改状态。
import { useImmer } from 'use-immer';
function App() {
const [user, setUser] = useImmer({
name : '张三',
age: 16
});
const handleClick = () => {
setUser(draft => {
draft.name = '李四'
})
}
return (
<div>
<div>name: {user.name} age: {user.age}</div>
<button onClick={handleClick}>click</button>
</div>
)
}
export default App;
总结
react中使用useState
创建状态变量,返回值是个数组分别是变量和更新函数,更新时要遵循immutable 编程规范使用更新函数修改数据,新手推荐看一下useImmer
以上就是对useState
的总结,如有不足还请各位大佬多多指点,希望对大家有所帮助,如果喜欢可以点赞,关注,后面也会持续更新更多优质文章。