dive into React Hooks useRef All In One
dive into React Hooks useRef All In One
useRef
https://beta.reactjs.org/apis/react#refs
https://reactjs.org/docs/hooks-reference.html#useref
https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables
function Timer() {
const intervalRef = useRef();
useEffect(() => {
const id = setInterval(() => {
// ...
});
intervalRef.current = id;
return () => {
clearInterval(intervalRef.current);
};
});
// ...
function handleCancelClick() {
clearInterval(intervalRef.current);
}
// ...
}
https://reactjs.org/docs/hooks-faq.html#how-to-create-expensive-objects-lazily
lazy initialization,once
react 性能优化
function Table(props) {
// ⚠️ createRows() is called on every render ❌
const [rows, setRows] = useState(createRows(props.count));
// ...
}
To avoid re-creating the ignored initial state, we can pass a function
to useState
:
function Table(props) {
// ✅ createRows() is only called once
const [rows, setRows] = useState(() => createRows(props.count));
// ...
}
function Image(props) {
const ref = useRef(null);
// ✅ IntersectionObserver is created lazily once
function getObserver() {
// ✅ ref.curren
if (ref.current === null) {
ref.current = new IntersectionObserver(onIntersect);
}
return ref.current;
}
// When you need it, call getObserver()
// ...
}
Refs
https://reactjs.org/docs/refs-and-the-dom.html
https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node
useCallback
function MeasureExample() {
const [height, setHeight] = useState(0);
const measuredRef = useCallback(node => {
if (node !== null) {
setHeight(node.getBoundingClientRect().height);
}
}, []);
return (
<>
<h1 ref={measuredRef}>Hello, world</h1>
<h2>The above header is {Math.round(height)}px tall</h2>
</>
);
}
error
Warning: You are calling ReactDOMClient.createRoot() on a container that has already been passed to createRoot() before. Instead, call root.render() on the existing root instead if you want to update it.
https://reactjs.org/docs/react-dom-client.html
https://github.com/reactwg/react-18/discussions/5
demos
import {
useEffect,
// useState,
useRef,
} from "react";
import { createRoot } from 'react-dom/client';
// import ReactDOM from 'react-dom';
export default function Home() {
const log = console.log;
// log(`v18 ReactDOM.createRoot =\n`, ReactDOM.createRoot);
log(`v18 createRoot =\n`, createRoot);
let root = useRef(null);
// let root = null;
useEffect(() => {
// v18
console.log(`root =`, root)
console.log(`root.current =`, root.current)
if(!root.current) {
const App = document.getElementById('v18-app');
// const root = ReactDOM.createRoot(App);
root.current = createRoot(App);
// JSX
root.current.render(<h1>Develop. Preview. Ship. 🚀 React v18 🆕</h1>);
}
}, []);
return (
<div id="v18-app">...loading</div>
)
}
Assignments to the 'root' variable from inside React Hook useEffect
will be lost after each render.
To preserve the value over time, store it in a useRef
Hook and keep the mutable value in the '.current'
property.
Otherwise, you can move this variable directly inside useEffect.eslintreact-hooks/exhaustive-deps
https://github.com/facebook/react/issues/14920
refs
©xgqfrms 2012-2021
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/16893280.html
未经授权禁止转载,违者必究!