阅读react文档

This commit is contained in:
2023-05-28 20:58:00 +08:00
parent 44f37fc0ff
commit bb73633973

View File

@@ -275,7 +275,103 @@ function Item({ name, isPacked }) {
return <li className="item">{name}</li>; return <li className="item">{name}</li>;
} }
``` ```
## 组件的渲染和提交
### 组件渲染的原因
- 组件的初次渲染
- 组件(或先祖组件)的状态发生了变化
#### 初次渲染
当引用启动时,会触发初次渲染
#### 状态更新时重新渲染
当初次渲染完成后可以通过set函数来更新state并触发渲染。更新组件状态会将重新渲染加入到队列。
对于初次渲染React会调用根部组件的方法来进行渲染而对于状态更新触发的渲染react只会调用状态更新对应组件的函数
> 对于组件的渲染其过程是递归的。如果待渲染的组件中包含了子组件那么react会对子组件进行渲染对子组件中包含的孙组件也同样。渲染会对组件子树中所有的组件进行渲染。
#### 渲染差异
React只会在渲染之间存在差异时才会更改React节点如一个节点如果渲染之间从父组件接受到了不同的props此时该组件才会发生重新渲染。
## state快照
在渲染函数中state的快照是不可变的即使在调用setState函数将更新state后旧组件中获取的state值仍然没有变化。
```js
// 即使调用setTitle此快照中的title值在setTitle之前和之后仍然没有变化
// 而新渲染的组件title初始值则为改变之后的值
function Title() {
const [title,setTitle]=useState('Morning News');
return (
<div>
<h1>{title}</h1>
<button onClick={
()=>{
alert(title);
setTitle(title==='Morning News'?'Evening Newng News':'Morning News');
alert(title);
}
}>Switch</button>
</div>
)
}
```
## 向setState中传入更新函数
react支持向setState中传入更新函数而不是更新后的值例如
```js
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);
```
此时react会将上述三个函数以此加入到队列中并在下次渲染时遍历执行队列中的函数。
## 更新state对象
如果向useState中传入object那么在调用setState函数时则是应该传入一个新的对象而不是在原有state对象上进行更新。
**应该将state对象看作是不可变的调用setState时应该创建一个state对象的副本并且修改副本对象后用副本对象的值去更新setState方法。**
```js
// 如果想要修改对象中的某个字段,可以使用如下方法
let oldObj = {
name : 'kazusa',
isMale: false,
};
let newObj = {
// 展开对象中的属性
...odlObj,
// 新设置某个属性,用于覆盖旧的值
name:'mashiro',
}
```
### 修改嵌套对象中的属性
```js
setPerson({
...person, // Copy other fields
artwork: { // but replace the artwork
...person.artwork, // with the same one
city: 'New Delhi' // but in New Delhi!
}
});
```
## Immer
如果要修改深层嵌套的state值可以引入Immer库来完成对象的拷贝工作。通过Immer库可以无需关心对象不可变而是直接以可变的语法来修改对象属性而Immer会实际帮忙处理对象不可便的工作。
```js
// 通过该import代替react中useState
import { useImmer } from 'use-immer';
// 然后可以直接修改对象中的值
const [person, updatePerson] = useImmer({
name: 'Niki de Saint Phalle',
artwork: {
title: 'Blue Nana',
city: 'Hamburg',
image: 'https://i.imgur.com/Sd1AgUOm.jpg',
}
});
function handleNameChange(e) {
updatePerson(draft => {
draft.name = e.target.value;
});
}
```
## 更新state数组
和object一样在react中数组应该也要是不可变的在更新state中的值时也应该再创建一个新的数组并用新的数组值设置