useCallback
先说一下使用的场景: 父组件包含子组件,子组件接收一个函数,当然子组件是完全展示类型。这时候当父组件更新的时候,子组件也会跟着更新渲染。如果没有更新的必要,这时候使用useCallback就可以进行限定只渲染1次了。 一般情况下useCallback会搭配react.memo一起来使用 或者配合useEfftect去使用,这样会提升性能问题,不然只用useCallback会产生额外的开销。
const Child = React.memo(function({val, onChange}) {
useEffect(() => {
console.log(val);
});
return <input value={val} onChange={onChange} />;
});
function App() {
const [val1, setVal1] = useState('');
const [val2, setVal2] = useState('');
const onChange1 = useCallback( evt => {
setVal1(evt.target.value);
}, []);
const onChange2 = useCallback( evt => {
setVal2(evt.target.value);
}, []);
return (
<>
<Child val={val1} onChange={onChange1}/>
<Child val={val2} onChange={onChange2}/>
</>
);
}
可以看到,一些无关useCallback函数之外的更新,不会更新useCallback包裹进来的子组件
useMemo
useCallback称做为缓存函数,那么useMemo则是缓存数据。 这种优化有助于避免在每次渲染时都进行高开销的计算,这个应该是很好理解了。
export default function App() {
const [count, setCount] = useState(0);
const [val, setValue] = useState('');
const getCount = useMemo(() => {
let sum = 0;
for (let i = 0; i < count * 100; i++) {
sum += i;
}
return sum;
}, [count]);
return
<div>
<button onClick={() => setCount(count + 1)}>+</button>
<input value={val} onChange={event => setValue(event.target.value)}/>
</div>
}
只有更新count的值的时候,才会重新刷新页面,重新计算结果
useRef
首先我们需要知道的是:useRef跟ref的功能性相同,但是无论页面怎么更新,useRef都不会改变,对于组件来说,是全局的。 具体使用看一下官方示例
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` 指向已挂载到 DOM 上的文本输入元素
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}