此次本文旨在讨论:vue
首先,咱们先阐述下 react 组件更新的策略:一个组件发生了更新,其子组件也会更新,在不进行优化的状况下,这种更新的传递会持续到组件树的叶子组件,即便某个子组件先后props并无发生改变。react
而后,让咱们肯定下什么能够引发组件更新(针对react 16):api
因为 useReducer 的 api 过于繁琐,为了叙述的方便,这里使用 useState 举例子。数组
这一节中,我使用 setState 指代 useState hook 返回的 setState 函数,而 this.setState 指代类组件的 setState 函数。promise
关于 useState hook 须要注意的几点:异步
hooks 给了函数组件和类组件同样保存状态的能力,天然而然的,既然能够保存状态就应该能够更改状态,useState 返回的 setState 能够用于改变相关的状态,自此函数组件和类组件同样,一样具备了主动发起更新的能力。函数
react 官方认为 useState hook 应该用于更加细粒度的值,因此 useState 和基本的值类型数据配合良好,可是若是牵扯 object 类型,就须要做出一些额外的考虑:优化
setState 和 this.setState 阻止更新的行为不同。不一样于 this.setState(null),setState(null) 依旧会触发更新,而且会把 state 赋值成 null。当你使用 setState 时,react 会将先后的 state 进行 === 比较,若是同样,则不会触发更新。因此若是你使用 useState 保存 object,即便新的 object 中的值没有发生变化,可是因为生成了新的引用,依旧会触发更新。这也是为何尽可能不要使用 useState 来储存 object,对于复杂的本地状态,建议使用 useReducer 来管理。this
关于 this.setState 须要的注意的是:spa
设置空对象 this.setState({}) 依旧会触发更新
this.setState(null) 不会触发更新
this.setState 同步异步问题:
在事件处理函数,或生命周期函数,react 会对 this.setState 做 batching 优化,此时 this.setState 是异步的。
其余时候,例如 setTimeout 或 promise 中,this.setState 是同步的。
这是我想咬文嚼字的一节,在阅读 react 相关文章时,常常会看到 props变化,致使组件发生了更新,这听起来似乎 react 在更新时会对比先后的 props,只有发生了变化时才会更新组件。又或者有过 vue 经验的新人,可能认为 react 对 props 对象进行了监听,因此发生变化时才会更新,然而,以上两种解释都是错误的。
function Box(props) {
const { count } = props;
return <div>{count}</div>;
}
function Counter() {
const [count, setCount] = useState(0);
const [useLessCount, setUseLessCount] = useState(0);
return (
<div> <Box count={count} /> <button onClick={() => setCount(prev => prev + 1)}>INC</button> <button onClick={() => setUseLessCount(prev => prev + 1)}>useLess</button> </div> ); } 复制代码
当 INC 按钮被点击时,Box 组件显示的数值加了 1,让咱们走一遍这个 更新 的流程,看看 props 变化是否致使了组件 更新
流程:
纵观整个流程,react 一直遵循着一个简单的策略 组件更新,则更新其全部的子组件,且不断递归的运用这个策略,直到叶子节点。和 props 自己没有任何关系。也就是说,子组件的更新是因为父组件更新引发的,而非 props 的变化
另外一个更直接的证据是,点击 useLess 按钮,一样会致使 Box 组件更新,即便 count 的值并无发生改变。
props 变化,致使组件发生了更新,犯了一个典型的因果谬误,A 先发生,而后 B 发生了,因此 A 致使了 B 发生。
这句话的主要问题在于,它会给初学者创建一种错误的心智模型,认为其中有什么 fancy 的 magic 发生,然而本质上只是遵循一个简单更新策略的天然而然的结果。
最后,任什么时候候,props 变化,致使组件发生了更新 这句话都是错误的,可是对于本小节中的例子来讲:props 变化,致使组件内容发生了变化 是正确的。
既然都谈了这么多,我就多说一点,人在交流时,假若不对一些模棱两可的词语的意思做出规定,很是容易变成你们自说自话,我不一样意你的,你不一样意个人,谁也说服了不了谁。我本觉得这是技术讨论的常识,然而却发现知乎上天天都在发生这样的对话,不多发现充满价值的讨论。