React函数组件状态-state
对象 state
state 中可以保存任意类型的 JavaScript 值,包括对象。但是,你不应该直接修改存放在 React state 中的对象。相反,当你想要更新⼀个对象时,你需要创建⼀个新的对象(或者将其拷⻉⼀ 份),然后将 state 更新为此对象。
官⽹说明:https://react.docschina.org/learn/updating-objects-in-state
改变对象state逻辑:
- 把所有存放在 state 中的 JavaScript 对象都视为只读的
- 你需要创建⼀个新对象并把它传递给 state 的设置函数
- 使⽤扩展运算符拷⻉对象 “…”
import React, { useState } from "react";
const App = () => {
const [message, setMessage] = useState({
name: "吴用",
website: "teacherself.com"
})
const changeName = () => {
setMessage({ ...message, name: "安徽吴彦祖",website:"asdasdas" })
}
return (
<div>
<h1>{message.name}</h1>
<h1>{message.website}</h1>
<button onClick={changeName}>更改title</button>
</div>
);
}
export default App;
改变嵌套对象逻辑
… 展开语法本质是“浅拷⻉”,它只会复制⼀层。当你想要更新⼀个嵌套属性时,你必须得多次使 ⽤展开语法。
setMessage({ ...message, staff: { ...message.staff, hobby: "洗脚" } });
使⽤ Immer 编写简洁的更新逻辑(针对复杂的对象数据!)
如果你的 state 有多层的嵌套,你或许应该考虑将其扁平化。但是,如果你不想改变 state 的数据结构,你可能更喜欢⽤⼀种更便捷的⽅式来实现嵌套展开的效果,Immer是⼀个⾮常流⾏的库,它可以让你使⽤简便但可以直接修改的语法编写代码,并会帮你处理好复制的过程。
安装:
npm install use-immer
引入
import { useImmer } from "use-immer";
使用:
import React from "react";
import { useImmer } from "use-immer";
const App = () => {
const [message, setMessage] = useImmer({
name: "吴用",
website: "teacherself.com"
})
const changeName = () => {
// setMessage({ ...message, name: "安徽吴彦祖",website:"asdasdas" })
setMessage((draft)=>{
draft.name = "安徽吴彦祖"
})
}
return (
<div>
<h1>{message.name}</h1>
<h1>{message.website}</h1>
<button onClick={changeName}>更改title</button>
</div>
);
}
export default App;
数组 state
数组是另外⼀种可以存储在 state 中的 JavaScript 对象,它虽然是可变的,但是却应该被视为不可
变。同对象⼀样,当你想要更新存储于 state 中的数组时,你需要创建⼀个新的数组(或者创建⼀
份已有数组的拷⻉值),并使⽤新数组设置 state。
改变数组state逻辑
- 数组是另一种对象,你需要将React state中的数组视为只读的。
- 不能直接修改原来数组,相反需要生成一个新的数组。
数组添加删除元素
import React, { useState } from "react";
const App = () => {
const [name, setName] = useState("")
const [person, setPerson] = useState([
{ id: 0, name: "老王" }
])
return (
<div>
<h1>react学习</h1>
<input value={name} onChange={(e) => { setName(e.target.value) }} />
<button onClick={() => {
setPerson([...person, { id: person.length, name: name }])
}}>添加</button>
<button onClick={() => {
setPerson(person.filter((i) => i.id !== item.id))
}}>删除</button>
<ul>
{person.map((item) => (
<li key={item.id}>{item.name}
<button onClick={() => {
setPerson(person.filter((i) => i.id !== item.id))
}}>删除</button>
</li>
))}
</ul>
</div>
);
}
export default App;
使⽤Immer编写简洁代码逻辑
import React, { useState } from "react";
import { useImmer } from "use-immer";
const App = () => {
const [name, setName] = useState("")
const [person, setPerson] = useImmer([
{ id: 0, name: "老王",check: false}
])
const handleChek=(id,checked)=>{
setPerson((darft)=>{
const checkItem = darft.find((i)=>i.id===id)
checkItem.check = checked
})
}
const deleteTab=(item)=>{
setPerson(person.filter((i)=>i.id!==item.id))
}
return (
<div>
<h1>react学习</h1>
<input value={name} onChange={(e) => { setName(e.target.value) }} />
<button onClick={() => {
setPerson([...person, { id: person.length, name: name,check: false}])
}}>添加</button>
<button onClick={() => {
// setPerson(person.filter((i) => i.id !== item.id))
setPerson(person.filter((i)=>!i.check))
}}>批量删除</button>
<ul>
{person.map((item) => (
<li key={item.id}>
<input type="checkbox" checked={item.check} onChange={(e)=>handleChek(item.id,e.target.checked)} />
{item.name}
<button onClick={()=>deleteTab(item)}>删除</button>
</li>
))}
</ul>
</div>
);
}
export default App;
react对象及其数组操作完结~