1、state、props、render函数之间的关系
当组件的state或props的值发生改变的时候,render函数就会重新执行;
当父组件的render函数被重新运行时,它的子组件的render函数都将被重新运行
2、虚拟DOM
虚拟DOM本质上就是一个js对象,用它来描述一个真实dom,当state数据发生变化的时候,会生成一个新的虚拟DOM,然后旧的虚拟DOM跟新的虚拟DOM进行对比,找到变化的部分,最后直接替换变化的部分即可:
流程:
3、diff算法
(1)同层对比,如果第一层就不一样,下一层就不用进行对比了,直接创建新的dom,用简单的算法进行比较,算法效率就会高
(2)用稳定的key进行对比,每个节点都有相对应的key值,在进行对比的时候,就很容易找出不同的节点,相同的节点就可以直接复用。尽量不要用index作为key值,因为如果数组发生变化,节点对应的index值就会发生变化。
4、setState和获取dom节点的时候会出现坑,例如,我要在数据改变之后获取dom的长度,如果是下面的写法,输出的结果跟真正的结果不一致,结果是每次都比实际的少一个dom元素
this.setState(()=>({
inputValue:value
}))
console.log(this.querySelectorAll('div').length)
原因是因为setState是一个异步操作,代码不会立即执行setState,会先执行console
解决办法:setState有两个参数,第一个是修改state值,第二个参数是个回调函数,修改完state值会后会执行这个函数里的代码,所以我们现在可以将console写进第二个函数里边,代码如下:
this.setState(()=>({
inputValue:value
}),()=>{
console.log(this.ul.querySelectorAll('div').length)
})
4、使用react-transition-group实现动画,去github搜索这个->Main documentation 有叫你怎么使用
//如果是yarn
yarn add react-transition-group
//如果是npm
npm install react-transition-group --save
地址:https://reactcommunity.org/react-transition-group/
基本使用方法:
import { CSSTransition } from 'react-transition-group';
render(){
return (
<CSSTransition
in={showMessage}
timeout={300}
classNames="alert"
unmountOnExit
onEnter={() => setShowButton(false)}
onExited={() => setShowButton(true)}
>
<div>helloe</div>
</CSSTransition>
)
}
如果是多个元素有动画的话TransitionGroup包着
<TransitionGroup className="todo-list">
{items.map(({ id, text }) => (
<CSSTransition
timeout={300}
classNames="alert"
unmountOnExit
onEnter={() => setShowButton(false)}
onExited={() => setShowButton(true)}
>
<div>helloe</div>
</CSSTransition>
))}
</TransitionGroup>