React.Component
class 组件
React.Component 是使用 ES6 classes 方式定义 React 组件的基类:
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
React.Component 并未实现 shouldComponentUpdate(),要手动用shouldComponentUpdate钩子函数优化react性能 shouldComponentUpdate(nextProps, nextState) 判断 React 组件的输出是否受当前 state 或 props 更改的影响。意思就是只要组件的 props 或者 state 发生了变化,就会重新构建 virtual DOM,然后使用 diff算法进行比较,再接着根据比较结果决定是否重新渲染整个组件。shouldComponentUpdate函数是重渲染时render()函数调用前被调用的函数,它接受两个参数:nextProps和nextState,分别表示下一个props和下一个state的值。并且,当函数返回false时候,阻止接下来的render()函数的调用,阻止组件重渲染,而返回true时,组件照常重渲染
React.PureComponent
class组件
React.PureComponent 与 React.Component 很相似。两者的区别在于 React.Component 并未实现 shouldComponentUpdate(),而 React.PureComponent 中以浅层对比 prop 和 state 的方式来实现了该函数。
如果赋予 React 组件相同的 props 和 state,render() 函数会渲染相同的内容,那么在某些情况下使用 React.PureComponent 可提高性能。 注意
React.PureComponent 中的 shouldComponentUpdate() 仅作对象的浅层比较。如果对象中包含复杂的数据结构,则有可能因为无法检查深层的差别,产生错误的比对结果。仅在你的 props 和 state 较为简单时,才使用 React.PureComponent,或者在深层数据结构发生变化时调用 forceUpdate() 来确保组件被正确地更新。你也可以考虑使用 immutable 对象加速嵌套数据的比较。
此外,React.PureComponent 中的 shouldComponentUpdate() 将跳过所有子组件树的 prop 更新。因此,请确保所有子组件也都是“纯”的组件。
React.memo
函数组件
const MyComponent = React.memo(function MyComponent(props) { /* 使用 props 渲染 */ }); React.memo 为高阶组件。
如果你的组件在相同 props 的情况下渲染相同的结果,那么你可以通过将其包装在 React.memo 中调用,以此通过记忆组件渲染结果的方式来提高组件的性能表现。这意味着在这种情况下,React 将跳过渲染组件的操作并直接复用最近一次渲染的结果。
React.memo 仅检查 props 变更。如果函数组件被 React.memo 包裹,且其实现中拥有 useState 或 useContext 的 Hook,当 context 发生变化时,它仍会重新渲染。
默认情况下其只会对复杂对象做浅层对比,如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现。
function MyComponent(props) { /* 使用 props 渲染 / } function areEqual(prevProps, nextProps) { / 如果把 nextProps 传入 render 方法的返回结果与 将 prevProps 传入 render 方法的返回结果一致则返回 true, 否则返回 false */ } export default React.memo(MyComponent, areEqual); 此方法仅作为性能优化的方式而存在。但请不要依赖它来“阻止”渲染,因为这会产生 bug。
注意
与 class 组件中 shouldComponentUpdate() 方法不同的是,如果 props 相等,areEqual 会返回 true;如果 props 不相等,则返回 false。这与 shouldComponentUpdate 方法的返回值相反。
React.FC
函数组件 React.FC<>的在typescript使用的一个泛型,FC就是FunctionComponent的缩写,是函数组件,在这个泛型里面可以使用useState
import React , {useState, useEffect} from 'react';
const MouseTracker: React.FC = ()=>{
const [position ,setPosition] = useState({x: 0, y: 0})
useEffect(()=>{
console.log('函数每次执行后render后会执行useEffect.......');
const updateMouse = (e:MouseEvent)=>{
setPosition({x: e.clientX, y: e.clientY})
}
document.addEventListener('click', updateMouse);
})
useEffect(()=>{
console.log('只在第一次函数执行后render后会执行useEffect.......');
const updateMouse = (e:MouseEvent)=>{
setPosition({x: e.clientX, y: e.clientY})
}
document.addEventListener('click', updateMouse);
},[])
useEffect(()=>{
console.log('只在第一次函数执行后render后会执行useEffect.......');
const updateMouse = (e:MouseEvent)=>{
setPosition({x: e.clientX, y: e.clientY})
}
document.addEventListener('click', updateMouse);
return ()=>{
console.log('组件卸载会执行这里,,,,,');
document.removeEventListener('click', updateMouse)
}
},[])
console.log('render,,,,,,,,position',position);
return (<p>position: x:{position.x},y:{position.y}</p>)
}
export default MouseTracker;