useMemo
const App = () => {
const [count, setCount] = React.useState(0);
const [num, setNum] = React.useState(1);
const handleClickOne = () => {
setCount(count + 1);
}
const handleClickTwo = () => {
setNum(num + 1);
}
const getVal = (val) => {
console.log('normal render');
return val + val;
}
const wrappedGetVal = (val) => {
console.log('memorized render');
return val + val;
}
const normalVal = getVal(count); // 当num变化的时候会执行
const memorizedVal = React.useMemo(() => {
wrappedGetVal(count);
}, [count]); // 当num变化的时候不会执行
<div>
<div onClick={handleClickOne}>count {count}</div>
<div onClick={handleClickTwo}>num { num }</div>
<div>{normalVal}normal</div>
<div>{memorizedVal}usememo</div>
</div>
}
useCallback
class Child extends React.Component {
shouldComponentUpdate(nextProps) {
console.log('this.props.memorizedFun', this.props.memorizedFun);
if(nextProps.memorizedFun === this.props.memorizedFun) {
console.log('memorizedFun equal'); // memorizedFun equal
return false
}
if(nextProps.normalClickFun === this.props.normalClickFun) {
console.log('normalClickFun equal'); // 不会进入这里
return false
}
return true;
}
render() {
console.log('child render----');
return (
<div>child click</div>
)
}
}
const App = () => {
const memorizedFun = React.useCallback(() => {
console.log('memorized callback');
}, [count]);
const normalClickFun = function() {
console.log('normalClickFun callback');
}
return (
<div>
<Child memorizedFun={memorizedFun} normalClickFun={normalClickFun} />
</div>)
}
useCallback和useEffect
1. useCallback有返回值
useEffect没有返回值
2. useCallback作用为性能优化
useEffect作用为执行副作用
3. useCallback在渲染期间执行
useEffect在渲染之后执行
Object.defineProperty()方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象
const a = 1;
正确的方式
读a的属性的时候,因为 a是number,实际会把a包装成基本包装类型 new Number(a)